如何通过属性值和 return 对象在命名空间中搜索 class?
How to search a class within a namespace by the value of an attribute and return an object?
我需要制作各种对象的工厂。尽可能抽象。能够通过参数从过去的条件创建各种对象,但不知道具体的 classes.
我想通过将枚举的值传递给工厂来完成此操作,并且它必须能够通过反射查找名称空间中所有使用值为的属性的 classes与最后一个参数相同。
我将留下以下代码片段作为参考。
具体例子class:
[Batatinha(SaborCode.Churrasco)]
internal class BatatinhaChurrasco : AbstractBatatinha
{
public override string Sabor
{
get { return "Churrasco"; }
}
}
这个工厂的例子:
internal class BatatinhaFactory
{
internal AbstractBatatinha GetBatatinha(SaborCode sabor)
{
// Some logic ... possibly using reflection.
}
}
所需调用示例:
AbstractBatatinha batatinha = new BatatinhaFactory().GetBatatinha(SaborCode.Churrasco);
Console.WriteLine(batatinha.Sabor);
// ==> "Churrasco"
观察:库应该是可移植的。 (.NET Framework 4.0.3, Silverlight 5, Windows 8, Windows Phone 8.1, Windows Phone Silverlight 8)
简而言之:给定枚举值,如何使用反射检索使用参数作为属性的 class 类型?
我想我明白你想做什么。我自己写了 类 并测试了这个:
public enum AttributeTypes
{
TypeA, TypeB
}
public class ReferencesEnumAttribute : Attribute
{
public AttributeTypes AttributeType { get; set; }
public ReferencesEnumAttribute(AttributeTypes attributeType)
{
AttributeType = attributeType;
}
}
public class FindsClassesByAttributeAndEnumValue
{
public Type[] FindClassesInAssemblyContaining<T>(AttributeTypes attributeType)
{
return typeof (T).Assembly.GetTypes()
.Where(type => type.GetCustomAttributes(false)
.Any(attribute => attribute is ReferencesEnumAttribute
&& ((ReferencesEnumAttribute) attribute).AttributeType == attributeType))
.ToArray();
}
}
然后是几个类属性:
[ReferencesEnum(AttributeTypes.TypeA)]
public class HasAttribute {}
[ReferencesEnum(AttributeTypes.TypeA)]
public class AlsoHasAttribute{}
[ReferencesEnum(AttributeTypes.TypeB)]
public class DoesntHaveAttribute {}
最后是单元测试:
[TestMethod]
public void GetClassesWithAttribute()
{
var finder = new FindsClassesByAttributeAndEnumValue();
var types = finder.FindClassesInAssemblyContaining<ReferencesEnumAttribute>(AttributeTypes.TypeA);
Assert.AreEqual(2, types.Length);
}
您还可以更进一步,对其施加约束,这样您就只能 return 从类型继承或实现接口的类型。否则你可能会得到除了属性之外没有任何共同点的类型。
public class FindsClassesByAttributeAndEnumValue
{
public Type[] FindClassesInAssemblyContaining<TContains,TInheritsFrom>(AttributeTypes attributeType)
where TInheritsFrom : class
{
return typeof (TContains).Assembly.GetTypes()
.Where(type =>
type.IsAssignableFrom(typeof(TInheritsFrom))
&& type.GetCustomAttributes(false)
.Any(attribute => attribute is ReferencesEnumAttribute
&& ((ReferencesEnumAttribute) attribute).AttributeType == attributeType))
.ToArray();
}
}
不建议在工厂中使用反射 类 因为它可能会导致您的代码出现性能问题。在代码中的某处使用反射,您将不得不使用 Activator.CreateInstance() 方法,这会导致您的应用程序出现性能问题,请查看此 post:Does System.Activator.CreateInstance(T) have performance issues big enough to discourage us from using it casually?
我需要制作各种对象的工厂。尽可能抽象。能够通过参数从过去的条件创建各种对象,但不知道具体的 classes.
我想通过将枚举的值传递给工厂来完成此操作,并且它必须能够通过反射查找名称空间中所有使用值为的属性的 classes与最后一个参数相同。
我将留下以下代码片段作为参考。
具体例子class:
[Batatinha(SaborCode.Churrasco)]
internal class BatatinhaChurrasco : AbstractBatatinha
{
public override string Sabor
{
get { return "Churrasco"; }
}
}
这个工厂的例子:
internal class BatatinhaFactory
{
internal AbstractBatatinha GetBatatinha(SaborCode sabor)
{
// Some logic ... possibly using reflection.
}
}
所需调用示例:
AbstractBatatinha batatinha = new BatatinhaFactory().GetBatatinha(SaborCode.Churrasco);
Console.WriteLine(batatinha.Sabor);
// ==> "Churrasco"
观察:库应该是可移植的。 (.NET Framework 4.0.3, Silverlight 5, Windows 8, Windows Phone 8.1, Windows Phone Silverlight 8)
简而言之:给定枚举值,如何使用反射检索使用参数作为属性的 class 类型?
我想我明白你想做什么。我自己写了 类 并测试了这个:
public enum AttributeTypes
{
TypeA, TypeB
}
public class ReferencesEnumAttribute : Attribute
{
public AttributeTypes AttributeType { get; set; }
public ReferencesEnumAttribute(AttributeTypes attributeType)
{
AttributeType = attributeType;
}
}
public class FindsClassesByAttributeAndEnumValue
{
public Type[] FindClassesInAssemblyContaining<T>(AttributeTypes attributeType)
{
return typeof (T).Assembly.GetTypes()
.Where(type => type.GetCustomAttributes(false)
.Any(attribute => attribute is ReferencesEnumAttribute
&& ((ReferencesEnumAttribute) attribute).AttributeType == attributeType))
.ToArray();
}
}
然后是几个类属性:
[ReferencesEnum(AttributeTypes.TypeA)]
public class HasAttribute {}
[ReferencesEnum(AttributeTypes.TypeA)]
public class AlsoHasAttribute{}
[ReferencesEnum(AttributeTypes.TypeB)]
public class DoesntHaveAttribute {}
最后是单元测试:
[TestMethod]
public void GetClassesWithAttribute()
{
var finder = new FindsClassesByAttributeAndEnumValue();
var types = finder.FindClassesInAssemblyContaining<ReferencesEnumAttribute>(AttributeTypes.TypeA);
Assert.AreEqual(2, types.Length);
}
您还可以更进一步,对其施加约束,这样您就只能 return 从类型继承或实现接口的类型。否则你可能会得到除了属性之外没有任何共同点的类型。
public class FindsClassesByAttributeAndEnumValue
{
public Type[] FindClassesInAssemblyContaining<TContains,TInheritsFrom>(AttributeTypes attributeType)
where TInheritsFrom : class
{
return typeof (TContains).Assembly.GetTypes()
.Where(type =>
type.IsAssignableFrom(typeof(TInheritsFrom))
&& type.GetCustomAttributes(false)
.Any(attribute => attribute is ReferencesEnumAttribute
&& ((ReferencesEnumAttribute) attribute).AttributeType == attributeType))
.ToArray();
}
}
不建议在工厂中使用反射 类 因为它可能会导致您的代码出现性能问题。在代码中的某处使用反射,您将不得不使用 Activator.CreateInstance() 方法,这会导致您的应用程序出现性能问题,请查看此 post:Does System.Activator.CreateInstance(T) have performance issues big enough to discourage us from using it casually?