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为可修改);
如果(!找到)
{