按字符串值获取类

我有一个带有一些派生类的抽象类

public abstract class MyObject { public string name { get; set; } public bool IsObject(string pattern); ... } public class MyObjectA : MyObject { public string name { get { return "MyObjectA"; } set; } public bool IsObject(string pattern) { ... } ... } public class MyObjectB: MyObject { public string name { get { return "MyObjectB"; } set; } public bool IsObject(string pattern) { ... } ... } 

现在我想要一个函数,它根据字符串返回我的特定类(MyObjectA / MyObectB)。 问题是,我有很多if / else-clause来得到它:

 public MyObject Create(string pattern) { MyObjectA obj = new MyObjectA(); if(obj.IsObject(pattern) { return obj; } else { MyObjectB objb = new MyObjectB(); if(objb.IsObject(pattern); return objb; else ... } } 

这看起来很可怕。 什么是更好的方法来做到这一点?

是的,使用Reflection。

您可以使用Type.GetType按字符串获取类的Type实例,然后使用Activator.CreateInstance实例化它,如下所示:

 public MyObject Create(string pattern) { Type t = Type.GetType(pattern); if (t == null) { throw new Exception("Type " + pattern + " not found."); } return Activator.CreateInstance(t); } 

您也可以使用Activator.CreateInstance(string, string)重载,但这不会直接返回所需Type的新实例。

您可以使用Reflection或System.Activator.CreateInstance基于Type或TypeName创建一个实例作为字符串。

正如Rudi Visser所说,你应该使用reflection 。

另外,为了获得您的class级名称,您不应该对其进行硬编码。 如果你想使用你的名字属性只需写

 public abstract class MyObject { public string name { get { return this.GetType().Name; } } public bool IsObject(string pattern); ... } 

如果你没有类的名称,只有一些表示它的字符串,那么你可以检查从MyObject派生的所有类

 public MyObject Create(string pattern) { Type[] types = Assembly.GetExecutingAssembly().GetTypes(); foreach (Type type in types.Where(t => t.IsSubclassOf(typeof(MyObject)))) { MyObject obj = (MyObject)Activator.CreateInstance(type); if (obj.name == pattern) { return obj; } } throw new Exception("Type " + pattern + " not found."); } 

你提出的问题有很多好的答案。 但是,我建议您使用工厂模式来满足此类要求。

您的“工厂”可以像向基类添加静态GetNewMyObject(string pattern)方法以及protected static Dictionary 。 然后,派生类可以简单地将它们的模式+类型添加到工厂(在静态构造函数中),从而允许将新的派生类添加到工厂而无需修改基类。

这样你的’pattern’字符串不必与类型名称匹配,也不需要像你可以写的那样进行任何逻辑模式匹配:

 public static MyObject GetNewMyObject(string pattern) { return (MyObject)Activator.CreateInstance(StaticTypeDictionary[pattern]); } 

它可以使用像这样的reflection来完成……

  public object getInstance(string assemblyName, string className, object[] constructorParameters) { System.Reflection.Assembly asm = System.Reflection.Assembly.Load(assemblyName); return asm.CreateInstance(className, false, System.Reflection.BindingFlags.CreateInstance, null, constructorParameters, null, null); } 

assemblyName – 完整路径+程序集名称

className – 完全限定的类名