2012-05-05 3 views
0

리플렉션, 구성 요소 모델 유형 설명자, 표현식 트리 및 애스펙트를 포함하여 다양한 방법으로이 작업을 수행했으나 아래 코드가 .Net을 사용하여 다음 목적을 모두 달성하는지 여부는 여전히 확실하지 않습니다. 4.0 이상 :PropertyInfo 이름 및 값 받기

  1. 하는 형태 보증 된 수는 속성 값을 제공 속성
  2. 의 이름을 입력 친화적 인 (마법의 문자열) 리팩토링하지 않으며, 여러 번 호출
  3. 이상 읽을 수
  4. 최대화 성능

코드가 어떻게 개선 될 수 있습니까?

protected void NotifyOfPropertyChanging<TProperty>(Expression<Func<TProperty>> property) { 
    var memberExpression = (MemberExpression)property.Body; 
    var prop = (PropertyInfo) memberExpression.Member; 

    var propertyName = prop.Name; 
    var value = prop.GetValue(this, null); 

    // fire INPC using propertyName 
    // use value and name to do IsDirty checking 
} 

답변

1

표현 트리를 컴파일하고 매번 GetValue을 호출하는 대신 나중에 사용할 수 있도록 캐싱하여 성능을 향상시킬 수 있습니다. 그러나 현재 구현에서 병목 현상이 발생하는 경우에만 이러한 최적화를 수행해야합니다.

void NotifyOfPropertyChanging<TProperty>(Expression<Func<TProperty>> property) 
{ 
    var memberExpression = (MemberExpression) property.Body; 
    var prop = (PropertyInfo) memberExpression.Member; 

    Func<TProperty> accessor; 
    if (!TypedAccessorCache<TProperty>.Cache.TryGetValue(prop, out accessor)) 
    { 
     accessor = property.Compile(); 
     TypedAccessorCache<TProperty>.Cache[prop] = accessor; 
    } 
    var value = accessor(); 

    // ... 
} 

static class TypedAccessorCache<TProperty> 
{ 
    public static readonly IDictionary<PropertyInfo, Func<TProperty>> Cache = 
     new Dictionary<PropertyInfo, Func<TProperty>>(); 
} 

캐시 사전 인스턴스를 보유하기 위해 일반 정적 유형을 사용했습니다. 이는 각각의 고유 한 특성 유형에 대해 별도의 유형화 된 캐시를 효과적으로 작성하는 편리한 방법입니다.

0

오랜 이야기이며 다른 접근 방식보다 나은 접근 방식은 아직 없습니다. 대부분의 일반적인 비즈니스 시나리오에서는 표현식이 성능 병목 현상을 일으키지 않을 것이라고 생각합니다 (나중에 필요하면 빠른 알림이 필요한 작은 코드를 최적화 할 수 있음). 따라서이 방법이 좋을 것입니다.

식 트리 만들기는 구문 분석에 훨씬 많은 시간이 소요되므로이 작업을 한 번만 수행해야합니다 (정적 클래스 수준의 식 변수 사용). 그러나이 경우에는 모델 코드가 약간 비대 해집니다.

저는 개인적으로 문자열 기반 INPC 처리를 선호합니다. ReSharper는 리팩토링과 관련하여 문자열로 잘 작동하므로 상대적으로 안전하게 호출 할 수 있습니다. 내가 아는 한, 이것은 가장 빠른 접근법입니다. VS 또는 ReSharper 스 니펫을 사용하면 여러 키 입력으로 속성을 쉽게 작성할 수 있습니다. 속성 값에 관하여

-는 사용되지 둘 의해을 INotifyPropertyChanging도 의해 인터페이스에서 INotifyPropertyChanged 아니다. 왜 그것을 필요로합니까?

+0

IsDirty 검사의 경우; 값이 캐시 된 값과 다른 경우 스냅 샷은 내 개체 IsDirty보다 큽니다. 건배 – Berryl