Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/304.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在运行时发现所有类,包括附加了属性的子类?_C#_Reflection_Static_Attributes_Static Constructor - Fatal编程技术网

C# 如何在运行时发现所有类,包括附加了属性的子类?

C# 如何在运行时发现所有类,包括附加了属性的子类?,c#,reflection,static,attributes,static-constructor,C#,Reflection,Static,Attributes,Static Constructor,我有一个属性,用于标记解决方案中的某些类。我必须检查这个属性是否在移动的对象上。这种检查(type.IsDefined(typeof(xmlimutableAttribute),true);)经常进行,这会成为一种负担并影响性能。我以前处理过一个类似的问题,找到所有附加了属性的类型并将它们存储在HashSet中,然后检查set.Contains(type)(参见我的答案)。这是我目前拥有的代码: public class XmlImmutableAttribute : XmlSerialized

我有一个属性,用于标记解决方案中的某些类。我必须检查这个属性是否在移动的对象上。这种检查(
type.IsDefined(typeof(xmlimutableAttribute),true);
)经常进行,这会成为一种负担并影响性能。我以前处理过一个类似的问题,找到所有附加了属性的类型并将它们存储在HashSet中,然后检查
set.Contains(type)(参见我的答案)。这是我目前拥有的代码:

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));
    } 
}
公共类XmlImmutableAttribute:XmlSerializedAttribute{
private static readonly HashSet m_xmlimutableAttributeType;//用于快速查找用xmlimutableAttribute标记的类型的集合
公共XmlImmutableAttribute(){
}
静态XmlImmutableAttribute(){//
m_xmlimutableAttributeType=new HashSet();
foreach(AppDomain.CurrentDomain.GetAssemblys()中的程序集){
foreach(在assembly.GetTypes()中键入Type){
if(type.IsDefined(typeof(xmlimutableAttribute),false)){
m_xmlimutableAttributeType.Add(类型);
}
}
}
}
公共静态bool IsAttachedTo(Type Type){//如果附加的类型被标记为不可变,则返回true
返回m_xmlimutableAttributeType.Contains(类型);
} 
public static bool IsAttachedTo(){//如果附加的类型标记为不可变,则返回true
返回IsAttachedTo(typeof(T));
} 
}
问题是
m_xmlimutableAttributeType
只会被初始化为包含直接附加属性的类型,而不是从附加类型中细分的类型。我假设这是在属性本身的静态构造函数中进行检查的问题,因为在静态初始化之后,当我对子类检查
type.IsDefined(typeof(xmlimutableAttribute),false)
时,它返回true。如何维护这种预先确定类型的模式以提高效率,同时让它检测附加属性的子类?

更改

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

要在继承链中搜索,请更改

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


要在继承链中搜索,我可能会重构您的属性以使用如下惰性初始化:

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 ) );
  }

}
公共类XmlImmutableAttribute:XmlSerializedAttribute
{
私有静态只读对象_syncroot=新对象();
私有静态HashSet _immutableTypes=null;
私有静态哈希集不可变类型
{
得到
{
锁定(\u syncroot)
{
if(_immutableTypes==null)
{
_immutableTypes=新哈希集(
应用程序域
.CurrentDomain
.getAssemblys()
.SelectMany(a=>a.GetTypes())
.Where(t=>t.IsDefined(typeof(xmlimutableAttribute),true))
) ;
}
}
返回不可变类型;
}
}
公共静态bool IsAttachedTo(类型)
{
bool isImmutable=ImmutableTypes.Contains(类型);
返回是可更改的;
}
公共静态bool IsAttachedTo()
{//如果附加的类型标记为不可变,则返回true
返回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) );
  }

}
公共类XmlImmutableAttribute:XmlSerializedAttribute
{
私有静态只读字典ImmutableTypes=新字典();
公共静态bool IsAttachedTo(类型)
{
如果(type==null)抛出新的ArgumentNullException(“type”);
布尔是可变的;
锁(不可变类型)
{
bool found=ImmutableTypes.TryGetValue(类型,out为可修改);
如果(!找到)
{
isImmutable=type.IsDefined(typeof(xmlimutableAttribute),true);
ImmutableTypes.Add(类型,isImmutable);
}
}
返回是可更改的;
}
公共静态bool IsAttachedTo()
{//如果附加的类型标记为不可变,则返回true
返回IsAttachedTo(typeof(T));
}
}

我可能会重构您的属性以使用如下惰性初始化:

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 ) );
  }

}
公共类XmlImmutableAttribute:XmlSerializedAttribute
{
私有静态只读对象_syncroot=新对象();
私有静态HashSet _immutableTypes=null;
私有静态哈希集不可变类型
{
得到
{
锁定(\u syncroot)
{
if(_immutableTypes==null)
{
_immutableTypes=新哈希集(
应用程序域
.CurrentDomain
.getAssemblys()
.SelectMany(a=>a.GetTypes())
.Where(t=>t.IsDefined(typeof(xmlimutableAttribute),true))
) ;
}
}
返回不可变类型;
}
}
公共静态bool IsAttachedTo(类型)
{
bool isImmutable=ImmutableTypes.Contains(类型);
返回是可更改的;
}
公共静态bool IsAttachedTo()
{//如果附加的类型标记为不可变,则返回true
返回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) );
  }

}
公共类XmlImmutableAttribute:XmlSerializedAttribute
{
私有静态只读字典ImmutableTypes=新字典();
公共静态bool IsAttachedTo(类型)
{
如果(type==null)抛出新的ArgumentNullException(“type”);
布尔是可变的;
锁(不可变类型)
{
bool found=ImmutableTypes.TryGetValue(类型,out为可修改);
如果(!找到)
{