C# 基于字符串实例化对象的最佳方法
我想讨论一下基于输入字符串实例化对象的最佳方法(在C#中)。让我解释一下。 假设我有一个基类:C# 基于字符串实例化对象的最佳方法,c#,reflection,factory,factory-pattern,C#,Reflection,Factory,Factory Pattern,我想讨论一下基于输入字符串实例化对象的最佳方法(在C#中)。让我解释一下。 假设我有一个基类: public abstract class BaseCar { public asbtract int GetEngineID(); //Other stuff... } 然后我有几个此类的实现,比如: public class SportCar : BaseCar { public override int GetEngine() { //Speci
public abstract class BaseCar
{
public asbtract int GetEngineID();
//Other stuff...
}
然后我有几个此类的实现,比如:
public class SportCar : BaseCar
{
public override int GetEngine()
{
//Specific implementation
}
}
public class OtherCar: BaseCar
{
public override int GetEngine()
{
//Specific implementation
}
}
等等
我想做的是创建一个静态CarFactory类,它有一个CreateCar
方法,该方法接受string
作为参数,并返回一个BaseCar
实例,具体取决于您给出的字符串。该字符串将是子类的名称
例如,如果我调用CarFactory.CreateCar('SportCar')
它应该返回一个SportCar实例
我知道我可以使用一个简单的switch语句来检查请求了哪辆车,并基于此创建一个新实例,但我不喜欢这种方法,原因有两个:
- 我计划有很多子类,硬编码每个
案例都不会太容易维护
- 我计划实现一个日化过程,为我创建的对象提供一些初始值(使用反射),所以混合硬编码和反射对我来说似乎不是一个好主意
Assembly.CreateInstance
来创建指定类的实例,但由于这是我第一次处理这个问题,我不知道是否有更好的方法来实现这一点。这是一种有效的方法吗
考虑到输入字符串将来自XML文件,是否有更简单的方法?也许我的问题已经在某个.NET程序集中得到了处理,而我却缺少了它。以下是我的想法。一个泛型工厂类,它自动注册作为给定类型的子类的所有类型,并允许您通过它们的名称实例化它们。这在某种程度上与注释中@Achiles链接的方法有关,只是没有与类型相关的初始化功能 不需要维护所有类型的枚举/开关组合。它还应该易于扩展,以处理建议的基于反射的初始化
static class StringFactory<T> where T : class
{
static private Dictionary<string, Type> s_dKnownTypes = new Dictionary<string, Type>();
static StringFactory()
{
RegisterAll();
}
static private void RegisterAll()
{
var baseType = typeof(T);
foreach (var domainAssembly in AppDomain.CurrentDomain.GetAssemblies())
{
foreach (var type in domainAssembly.GetTypes()
.Where(t => t.IsSubclassOf(baseType)))
{
s_dKnownTypes.Add(type.Name, type);
}
}
}
static public T Create(string _sTypeName)
{
Type knownType;
if (s_dKnownTypes.TryGetValue(_sTypeName, out knownType))
{
return (T)Activator.CreateInstance(knownType);
}
throw new KeyNotFoundException();
}
}
静态类StringFactory,其中T:class
{
静态私有字典s_dKnownTypes=新字典();
静态StringFactory()
{
registeral();
}
静态私有void RegisterAll()
{
var baseType=类型(T);
foreach(AppDomain.CurrentDomain.GetAssemblys()中的var domainAssembly)
{
foreach(domainAssembly.GetTypes()中的变量类型)
.其中(t=>t.IsSubclassOf(baseType)))
{
添加(type.Name,type);
}
}
}
静态公共文件不能创建(字符串_sTypeName)
{
类型知识型;
if(s_dKnownTypes.TryGetValue(_sTypeName,out knownType))
{
return(T)Activator.CreateInstance(knownType);
}
抛出新的KeyNotFoundException();
}
}
假设问题的类别存在,您将实例化一辆特定的汽车,如下所示:
var car = StringFactory<BaseCar>.Create("SportsCar");
DoSomethingWith(car.EngineID());
var-car=StringFactory.Create(“跑车”);
DoSomethingWith(car.EngineID());
既然你的问题是为了讨论最好的方法,请考虑这只是其中的一个。我没有在生产环境中使用过这种方法,完全有可能它是针对您的特定情况的错误方法。不过,它足以说明一般原理,应该为进一步讨论提供一个起点。这里的相同查询(针对java)。。应该提供一些提示:感谢您的想法,实际上我认为注册所有可用类型一次,然后使用数据结构映射它们是一种很好的方法,而不是每次重新请求实例时都在程序集中查找指定的类型。