C# 如何基于枚举的名称动态创建对象?无开关
我有类似的东西C# 如何基于枚举的名称动态创建对象?无开关,c#,enums,C#,Enums,我有类似的东西 enum Animal { Cat, Dog, Cow, Pigeon } 和阶级 public class Cow { } public class Dog { } public class Cow { } public class Pigeon { } 这就是我想要实现的,基于所选enumu动态创建一个类对象。枚举和类名总是相同的。Enum和类有几十个,所以我不想为每一对添加另一个案例 e、 问题 公共对象GetAnimal(动物)
enum Animal
{
Cat,
Dog,
Cow,
Pigeon
}
和阶级
public class Cow
{ }
public class Dog
{ }
public class Cow
{ }
public class Pigeon
{ }
这就是我想要实现的,基于所选enumu动态创建一个类对象。枚举和类名总是相同的。Enum和类有几十个,所以我不想为每一对添加另一个案例
e、 问题
公共对象GetAnimal(动物)
像
GetAnimal(Animal.Cow)一样使用代码>应返回新的Cow类对象。另一种方法是使用自定义属性和扩展方法,将方法的语法等价物添加到枚举中。公认的答案简单得多,因此可能更好,但您可能会对此感兴趣
public object GetAnimal(Animal animal)
{
var ns = typeof(Animal).Namespace; //or your classes namespace if different
var typeName = ns + "." + animal.ToString();
return Activator.CreateInstance(Type.GetType(typeName));
}
using System;
using System.Reflection;
namespace CustomAttributes
{
[AttributeUsage(AttributeTargets.Field)]
public class ConstructableEnumAttribute : Attribute
{
public Type Type { get; set; }
public ConstructableEnumAttribute(Type type)
{
this.Type = type;
}
}
public static class AnimalExtension
{
// This is your main mapping method. It doesn't need to be an extension
// method, so you could get the 'Construct(Animal.Cat)' syntax you requested,
// but I like the ability to do:
// Animal myPet = Animal.Cat;
// object animal = myPet.Construct();
public static object Construct(this Animal ofAnimal)
{
object animal = null;
Type typeOfAnimal = GetType(ofAnimal);
if ((null != typeOfAnimal) &&
(!typeOfAnimal.IsAbstract))
{
animal = Activator.CreateInstance(typeOfAnimal);
}
return animal;
}
private static Type GetType(Animal animal)
{
ConstructableEnumAttribute attr = (ConstructableEnumAttribute)
Attribute.GetCustomAttribute
(ForValue(animal), typeof(ConstructableEnumAttribute));
return attr.Type;
}
private static MemberInfo ForValue(Animal animal)
{
return typeof(Animal).GetField(Enum.GetName(typeof(Animal), animal));
}
}
public enum Animal
{
[ConstructableEnum(typeof(Cat))]
Cat,
[ConstructableEnum(typeof(Dog))]
Dog,
[ConstructableEnum(typeof(Cow))]
Cow,
[ConstructableEnum(typeof(Pigeon))]
Pigeon
}
public class Cat
{ }
public class Dog
{ }
public class Cow
{ }
public class Pigeon
{ }
public class Owner
{
Animal pet;
Owner(Animal animal)
{
pet = animal;
}
public void ShowPet()
{
object theCreature = pet.Construct();
Console.WriteLine("My pet is a " + theCreature.GetType().ToString());
}
}
}
您可以使用字典
,它将枚举值映射到创建对象的函数。但坦率地说,我不认为在switch语句中添加大小写或添加新的词典条目有什么关系。这是一门艺术。效果很好。我更喜欢这个解决方案,而不是公认的答案。当类名被重构时,这不会中断。