2013-12-03 8 views
1

내 솔루션에서 특정 클래스를 표시하는 데 사용하는 특성이 있습니다. 이 속성이 움직이는 객체에 있는지 확인해야합니다. 이 수표 (type.IsDefined(typeof(XmlImmutableAttribute), true);)는 너무 자주 수행되고있어 부담이되어 성능이 저하되고 있습니다. 이전에 유사한 문제를 처리하기 전에 첨부 된 속성을 가진 모든 유형을 찾고 HashSet에 저장하고 set.Contains(type); (내 대답 here 참조)을 확인했습니다. 이것은 내가 현재 가지고 코드 :왔다 종류의런타임에 속성이 첨부 된 하위 클래스를 포함한 모든 클래스를 찾는 방법은 무엇입니까?

public class XmlImmutableAttribute : XmlSerializedAttribute { 

    private static readonly HashSet<Type> m_XmlImmutableAttributeTypes; // Set for the quick lookup of types that are marked with the XmlImmutableAttribute 

    public XmlImmutableAttribute() { 
    } 

    static XmlImmutableAttribute() { // 
      m_XmlImmutableAttributeTypes = new HashSet<Type>(); 
      foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies()) { 
       foreach (Type type in assembly.GetTypes()) { 
        if (type.IsDefined(typeof(XmlImmutableAttribute), false)) { 
         m_XmlImmutableAttributeTypes.Add(type); 
        } 
       } 
      } 
    } 

    public static bool IsAttachedTo(Type type) { // returns true if the attached type is marked immutable 
     return m_XmlImmutableAttributeTypes.Contains(type); 
    } 

    public static bool IsAttachedTo<T>() { // returns true if the attached type is marked immutable 
     return IsAttachedTo(typeof(T)); 
    } 
} 

문제는, m_XmlImmutableAttributeTypes는 직접 연결된 특성을 갖는 유형을 포함하도록 초기화 될 것입니다 및 비 하위에 부착 된 유형으로 분류. 정적 초기화 후 서브 클래스 에서 type.IsDefined(typeof(XmlImmutableAttribute), false)을 확인하면 true를 반환하기 때문에이 속성 자체의 정적 생성자에서 검사가 수행되는 문제라고 가정합니다. 효율성을 높이기 위해 유형을 미리 결정하는 패턴을 유지하면서 속성을 첨부 한 하위 클래스를 감지하는 방법은 무엇입니까?

답변

1

변경

if (type.IsDefined(typeof(XmlImmutableAttribute), false)) 

아마 같은 게으른 초기화를 사용하도록 속성을 리팩토링 것

0

if (type.IsDefined(typeof(XmlImmutableAttribute), true)) 

은 상속 체인에서 검색 할에 :

public class XmlImmutableAttribute : XmlSerializedAttribute 
{ 

    private static readonly object _syncroot  = new object() ; 
    private static HashSet<Type> _immutableTypes = null ; 
    private static HashSet<Type> ImmutableTypes 
    { 
    get 
    { 
     lock (_syncroot) 
     { 
     if (_immutableTypes == null) 
     { 
      _immutableTypes = new HashSet<Type>(
           AppDomain 
           .CurrentDomain 
           .GetAssemblies() 
           .SelectMany(a => a.GetTypes()) 
           .Where(t => t.IsDefined(typeof(XmlImmutableAttribute) , true)) 
          ) ; 
     } 
     } 
     return _immutableTypes ; 
    } 
    } 

    public static bool IsAttachedTo(Type type) 
    { 
    bool isImmutable = ImmutableTypes.Contains(type) ; 
    return isImmutable ; 
    } 

    public static bool IsAttachedTo<T>() 
    { // returns true if the attached type is marked immutable 
    return IsAttachedTo(typeof(T)); 
    } 

} 

그것이 작동하지 않는다면, 다른 접근법은 검색을 캐쉬하는 것입니다 :

public class XmlImmutableAttribute : XmlSerializedAttribute 
{ 

    private static readonly Dictionary<Type,bool> ImmutableTypes = new Dictionary<Type,bool>() ; 

    public static bool IsAttachedTo(Type type) 
    { 
    if (type == null) throw new ArgumentNullException("type"); 
    bool isImmutable ; 
    lock (ImmutableTypes) 
    { 
     bool found = ImmutableTypes.TryGetValue(type, out isImmutable) ; 
     if (!found) 
     { 
     isImmutable = type.IsDefined(typeof(XmlImmutableAttribute),true) ; 
     ImmutableTypes.Add(type,isImmutable) ; 
     } 
    } 
    return isImmutable ; 
    } 

    public static bool IsAttachedTo<T>() 
    { // returns true if the attached type is marked immutable 
    return IsAttachedTo(typeof(T)); 
    } 

}