2011-03-31 1 views
1

이전 질문에서 Linq expressions and extension methods to get property name 표현식과 확장명을 사용하는 두 POCO 속성 간의 데이터 바인딩에 대해 질문했습니다. 도움이되는 anser가 있는데 제대로 작동하지만 질문이 있습니다. 여기 람다 식으로 컴파일 할 때 속성 이름을 확인하십시오.

코드입니다 :

public static class Extensions 
{ 
    public static void Bind<TSourceProperty, TDestinationProperty>(this INotifyPropertyChanged source, Expression<Func<TSourceProperty, TDestinationProperty>> bindExpression) 
    { 
     var expressionDetails = GetExpressionDetails<TSourceProperty, TDestinationProperty>(bindExpression); 
     var sourcePropertyName = expressionDetails.Item1; 
     var destinationObject = expressionDetails.Item2; 
     var destinationPropertyName = expressionDetails.Item3; 

     // Do binding here 
     Console.WriteLine("{0} {1}", sourcePropertyName, destinationPropertyName); 
    } 

    private static Tuple<string, INotifyPropertyChanged, string> GetExpressionDetails<TSourceProperty, TDestinationProperty>(Expression<Func<TSourceProperty, TDestinationProperty>> bindExpression) 
    { 
     var lambda = (LambdaExpression)bindExpression; 

     ParameterExpression sourceExpression = lambda.Parameters.FirstOrDefault(); 
     MemberExpression destinationExpression = (MemberExpression)lambda.Body; 

     var memberExpression = destinationExpression.Expression as MemberExpression; 
     var constantExpression = memberExpression.Expression as ConstantExpression; 
     var fieldInfo = memberExpression.Member as FieldInfo; 
     var destinationObject = fieldInfo.GetValue(constantExpression.Value) as INotifyPropertyChanged; 

     return new Tuple<string, INotifyPropertyChanged, string>(sourceExpression.Name, destinationObject, destinationExpression.Member.Name); 
    } 
} 

사용법 :

위 대한 내 질문에

public class TestSource : INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 

    public string Name { get; set; }   
} 

public class TestDestination : INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 

    public string Id { get; set; }  
} 

class Program 
{   
    static void Main(string[] args) 
    { 
     var x = new TestSource(); 
     var y = new TestDestination(); 

     x.Bind<string, string>(Name => y.Id); 
    }  
} 
은 다음과 같습니다
  • 내가 호출은 바인딩 할 수 있도록

    두 번째 매개 변수는의 구성원입니다.현재 클래스, 그래서 뭔가를 가지고 같은 x.Bind (Name => Id); x.Bind (Name => y.Id) 대신에. 이 경우 destinationExpression.Expression은 MemberExpression 대신 ConstantExpression이므로 바인딩이 실패합니다. 나는 무엇을 이 경우에 로 변경해야 할 지 모르겠습니다.

  • 속성 이름이 잘못된 경우 (예 : x.Bind (Na123me => Id)) 컴파일 타임에 실패하게하는 방법이 있습니까?

답변

0

아니요. 사실, 당신은 단지 이런 식을보다 쉽게 ​​만들 수 있도록 트릭을 사용하고 있습니다. 그러나 람다식이 컴파일 타임에 특정 패턴을 따르도록 강제 할 방법이 없습니다. LINQ to Entities와 같은 기술은 많은 런타임 예외를 생성하는 경향이 있습니다.