我需要建造各种物品的工厂。要尽可能抽象。能够通过参数从过去的条件创建各种对象,但没有蹩脚的具体类。
我想通过将枚举值传递给工厂来实现这一点,并且它必须能够通过反射查找命名空间中的所有类,这些类使用的值与最后一个参数的值相同。
我留下以下代码段作为参考。
具体类的一个例子:
[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"
Obs。:图书馆应该是便携式的。 (.NET Framework 4.0.3,Silverlight 5,Windows 8,Windows Phone 8.1,Windows Phone Silverlight 8)
简而言之:鉴于枚举的值,如何使用反射检索将该参数用作属性的类的类型?
答案 0 :(得分:1)
我想我明白你要做的事情。我编写了自己的类并对其进行了测试:
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);
}
您还可以更进一步,并对其进行约束,以便您只返回从类型继承或实现接口的类型。否则你可以找回除属性之外没有任何共同点的类型。
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();
}
}
答案 1 :(得分:0)
不建议在工厂类中使用反射,因为它可能会导致代码出现性能问题。在代码中的某处使用反射,您将不得不使用Activator.CreateInstance()方法,这会导致应用程序出现性能问题,请查看以下帖子:Does System.Activator.CreateInstance(T) have performance issues big enough to discourage us from using it casually?