2012-07-06 2 views
2

나는 다음과 같은 확장 방법이 있습니다 강력한 입력을 제공하는 대신 문자열의 속성 이름을 전달할 때linq 표현식에서 정보를 검색 할 때 리플렉션이 사용됩니까?

public static string ToPropertyName<T,E>(this Expression<Func<E, T>> propertyExpression) 
{ 
    if (propertyExpression == null) 
     return null; 

    string propName; 
    MemberExpression propRef = (propertyExpression.Body as MemberExpression); 
    UnaryExpression propVal = null; 

    // -- handle ref types 
    if (propRef != null) 
     propName = propRef.Member.Name; 
    else 
    { 
     // -- handle value types 
     propVal = propertyExpression.Body as UnaryExpression; 
     if (propVal == null) 
      throw new ArgumentException("The property parameter does not point to a property", "property"); 
     propName = ((MemberExpression)propVal.Operand).Member.Name; 
    } 

    return propName; 
} 

내가 LINQ 식을 사용하고 난 문자열로 속성의 이름을 검색에이 기능을 사용합니다. 이 방법은 리플렉션을 사용합니까?

내가 묻는 이유는이 방법이 코드에서 상당히 많이 사용 되었기 때문에 내가 충분히 합리적인 속도로 전달되기를 바랍니다.

+0

http://stackoverflow.com/questions/4803272/in-c-is-expression-api-better-than-reflection?lq=1 – nawfal

+0

[λ 표현식 기반 반사 대 정상 반사] 가능한 중복 (http : // stackoverflow.com/questions/2697655/람다 식 기반 반사 대 정상 반사) – nawfal

답변

2

필자가 아는 한, 반사는 일종의 동적 유형 인트로 스펙이 장면 뒤에서 발생한다는 의미에서 관련되지 않습니다. 그러나 System.Reflection (예 : Type 또는 PropertyInfo) 유형은 System.Linq.Expressions 네임 스페이스의 유형과 함께 사용됩니다. 이 클래스는 컴파일러에서 을 추상 구문 트리 (AST)로 전달하는 데 사용됩니다. Func<T,E>에서 표현식 트리로의 변환은 런타임에가 아니라 컴파일러에 의해 수행되기 때문에 람다의 정적 측면 만 설명됩니다.

실행 시간에 람다에서이 표현식 트리 (복잡한 객체 그래프)를 작성하는 것은 더 많은 객체를 인스턴스화해야하기 때문에 단순히 속성 이름 문자열 (단일 객체)을 전달하는 것보다 다소 오래 걸릴 수 있음을 기억하십시오. 메서드에 전달 된 람다의 복잡성에 따라 다르지만) 동적 유형 검사 인 someObject.GetType()이 관련되어 있지 않습니다. 예

:

Expression<Func<int, bool>> lambda1 = num => num < 5; 

컴파일러에 의해이 같은 것으로 변환 :

This MSDN article는 다음 람다 식을 보여줍니다이 넘어

ParameterExpression numParam = Expression.Parameter(typeof(int), "num"); 
ConstantExpression five = Expression.Constant(5, typeof(int)); 
BinaryExpression numLessThanFive = Expression.LessThan(numParam, five); 
Expression<Func<int, bool>> lambda1 = 
    Expression.Lambda<Func<int, bool>>(
     numLessThanFive, 
     new ParameterExpression[] { numParam }); 

, 다른 어떤 것도 일어나지 않는다 . 그래서 이것은 당신의 방법으로 전달 될 수있는 객체 그래프입니다.

0

메소드 이름이 ToPropertyName이므로 클래스의 특정 속성에 대한 유형이 지정된 이름을 얻으려고한다고 가정합니다. Expression<Func<E, T>> 접근 방식을 벤치마킹 했습니까? 표현식을 만드는 데 드는 비용은 상당히 큽니다. 메소드가 정적이기 때문에 멤버 식을 캐싱하지 않습니다. 즉, 표현 방식이 리플렉션을 사용하지 않더라도 비용이 높을 수 있습니다. 이 질문을 참조하십시오 How do you get a C# property name as a string with reflection?를 다른 접근 방식이 여기서

public static string GetName<T>(this T item) where T : class 
{ 
    if (item == null) 
     return string.Empty; 

    return typeof(T).GetProperties()[0].Name; 
} 

당신은이 같은 속성 또는 변수의 이름을 얻을하는 데 사용할 수 있습니다 :

new { property }.GetName(); 

를 더욱 속도를 높이려면을, 당신은해야합니다 회원 정보를 캐시하십시오. 당신이 가지고있는 것이 절대적으로 Func<E, T>이라면 당신의 접근 방식이 적합합니다. 또한이 참조 : lambda expression based reflection vs normal reflection

이와 관련된 질문 참조 : Get all the property names and corresponding values into a dictionary