我有一个属性用于标记解决方案中的某些类。我必须检查此属性是否在移动的对象上。这项检查(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。如何保持这种预先确定类型的模式以提高效率,同时还要检测附加了属性的子类?
答案 0 :(得分:1)
更改
if (type.IsDefined(typeof(XmlImmutableAttribute), false))
到
if (type.IsDefined(typeof(XmlImmutableAttribute), true))
在继承链中搜索
答案 1 :(得分:0)
我可能会重构你的属性以使用这样的延迟初始化:
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) );
}
}