如果我这样做,我会在我的程序中枚举所有类型:
List<SerializableAttribute> attributes=new List<SerializableAttribute>() ;
foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies())
{
foreach (Type type in assembly.GetTypes())
{
attributes.AddRange(
type.GetCustomAttributes(false)
.OfType<SerializableAttribute>()
.ToList());
}
}
.NET dll附带的元数据是否被索引以允许我执行以下操作:
List<SerializableAttribute> attributes = typeof(SerializableAttribute)
.GetClassesIAmDefinedOn();
我还有其他选择吗?
(SerializableAttribute只是一个例子)
答案 0 :(得分:8)
好吧,使用更多LINQ并使用IsDefined
至少使代码更好(并获取类型,而不是属性......)
var types = (from assembly in AppDomain.CurrentDomain.GetAssemblies()
from type in assembly.GetTypes()
where Attribute.IsDefined(type, typeof(SerializableAttribute))
select type).ToList();
现在,您询问效率 - 这需要多长时间?它需要多长时间可接受?你经常打电话吗? (这看起来很奇怪。)
另请注意,它仅包含已加载的程序集 - 可能存在尚未加载的引用程序集;那个没被拿起的重要吗?
答案 1 :(得分:7)
在这里通常使用效率最高的是Attribute.IsDefined(...)
,尽管在[Serializable]
的特定情况下,type.IsSerializable
是更快(在这种情况下它实际上并不存储为属性 - 它在编译器中有特殊处理,映射到CLI标志)。
答案 2 :(得分:2)
不,不是。并注意GetCustomAttributes。它非常昂贵,没有有效缓存。 AppDomain.Current.Domain.GetAssemblies也非常昂贵。
要做这样的事情,我在字典中保留一个缓存
var cache = new Dictionary<Assembly,Attribute[]>();
foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies())
{
var attributes = new List<SerializableAttribute>();
foreach (Type type in assembly.GetTypes())
{
attributes.AddRange(
type.GetCustomAttributes(false)
.OfType<SerializableAttribute>()
.ToList());
}
cache[assembly] = attributes.ToArray();
}
答案 3 :(得分:1)
您可以这样做:
var assem = // get assembly:
var types = assem.GetTypes().Where(t => t.IsDefined(typeof(SerializableAttribute)));
或者,如果你想反过来这样做:
public static IEnumerable<Type> WhereDefinedOn(this Type type, IEnumerable<Type> types)
{
if (!typeof(Attribute).IsAssignableFrom(type))
throw new InvalidOperationException("Only attribute types are supported.");
return types.Where(t => t.IsDefined(type));
}
您可以将其用作:
var allTypes = assem.GetTypes();
var filteredTypes = typeof(SerializableAttribute).WhereDefinedOn(allTypes);