2010-12-09 2 views

답변

3

예, 가능합니다. 그러나 표현식 트리 다시 쓰기기를 올바르게 구현하는 것보다 훨씬 복잡합니다. 특히 필드, 속성, 인덱싱 된 속성, 메서드 호출 및 임의의 식에서 유효한 다른 구문을 올바르게 처리 할 수 ​​있어야하는 경우.

식을 계산할 때마다 식 트리를 매번 람다 함수로 동적으로 컴파일해야하기 때문에 가장 잘 수행되는 연산이 아닐 수도 있습니다.

implementation on this pattern on CodePlex입니다. 필자는 개인적으로 그것을 사용한 적이 없기 때문에 구현 방법이 얼마나 잘되어 있는지 또는 내가 설명한 모든 사례를 처리하는지 여부를 말할 수는 없습니다.

식 트리를 다시 작가를 작성하는 대신, 이러한 경우에 default(T)을 반환, (오히려 식 트리보다) 람다 기능을 적용 Maybe()를 작성하고 던져 어떤 ArgumentNullException를 잡을 것입니다. 그것은 많은 사람들에게 이런 식으로 흐름 제어를위한 예외를 사용하는 잘못 된 방법을 문질러 주지만 ... 확실히 올바른 방법은 구현하기 쉽습니다. 개인적으로는 피할 수있는 식의 일부로 호출되는 메서드 내에서 null 참조 오류를 가릴 수 있으므로 직접 사용하지 마십시오.

0

간단한 대답 객체가 만들 저렴하고 널 (null) 검사를 피하려는 경우 :

myOrder.NewIfNull().Customer.NewIfNull().City; 

이 null 또는 당신이 도시의 생성자 또는 필드 초기화 설정 몇 가지 초기 값 중 하나를 반환합니다. NewIfNull는-내장되지 않지만 실제 쉽다 :

public static T NewIfNull<T>(this T input) where T:new() 
{ 
    return input ?? new T(); 
} 
+0

새 개체를 만들면 의도하지 않은 결과가 발생할 수 있습니다. – Amy

0

내가 (CodeProject의 기사에 따라) 어쩌면 내 구현 비용을 운반 것을 알고,하지만 난 그것을 얻기의 아이디어에 비해 아무것도 없습니다 확신 : 당신이 관심이 있다면

는 봐 그곳에는 Expression<T>이 있습니다. 근본적으로 당신은 반사를 모든 방법으로 말하고 있습니다. Roslyn 스타일의 미리 컴파일 된 것이라면 괜찮습니다.하지만 아직 없습니다.

필자의 구현의 장점은 신화를 넘어서는 것이라고 주장하겠습니까? 운영자. 이와 같은 체인을 사용하여 전체 알고리즘을 작성하는 기능은 자신의 저작물 (예 : If, Do 등)을 주입하고 자신 만의 특수한 논리를 제공 할 수 있음을 의미합니다.

여기가 당신이하려는 것보다 더 복잡하다는 것을 알고 있지만, C# 5에서 null-coalescing 도트 연산자를 얻지 못하는 것처럼 보입니다.내 마음에 와서

1

몇 가지 포인트 :

  • .Solutions 메모리 개체에 대해 잘 작동하지만, 이러한 정적 호출이 영구 저장소에 대해 실행하는 변환 할 수 없습니다로 EF에 문제로 실행 (즉, SQL입니다 DB). 이것은 응용 범위를 어느 정도 크게 제한합니다.

  • 체인이 유효한 결과를 산출했는지 항상 알고 싶습니다. 따라서 어떤 경우 든 하나의 조건부 블록 if(city == null)을 갖게됩니다.

  • "못생긴"이외의 현재 솔루션에는 표현식이 포함됩니다. 그 중 하나가 끝 (참 반환)에 도달 또는 null 값 속성 (false를 반환)을 만날 때까지

따라서, 내 선택이

var property = (() => myOrder.Customer.City); 
city = HasValue(property) ? property.Invoke() : "unknown"; 

HasValue(Expression e) 같은 것 재귀 LINQ 표현 트리를 통해 안내합니다. 구현은 간단해야하며 MethodInfo MemberMemberExpression 클래스를 사용하여 AST를 구문 분석하십시오. Brian이 제안한 것처럼 getter를이 방법으로 구현할 수도 있지만 HasValue은 항상 bool을 반환하기 때문에 위의 것을 더 좋아합니다. 또한 :

  • 구성원 호출도 처리 할 수 ​​있습니다.
  • 평가는 myOrder.HasValue(x => x.Customer.City)으로 만들 수 있지만 약간의 복잡성이 있습니다.
관련 문제