基于字符串实例化对象的最佳方法

安德鲁

我想讨论有关基于输入字符串实例化对象的最佳方法(在C#中)。让我解释。假设我有一个基类:

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接受astring作为参数并返回BaseCar实例的方法,具体取决于您提供的字符串。该字符串将是子类的名称。

例如,如果我调用CarFactory.CreateCar('SportCar')它,应返回SportCar实例。

我知道我可以使用简单的switch语句来检查已请求的汽车并基于该请求创建新实例,但是由于两个原因,我不喜欢这种方法:

  • 我打算有很多子类,硬编码每一个case也不会太容易十个分量
  • 我计划实现一个初始化过程,以便也为我创建的对象提供一些初始值(使用反射),因此混合硬编码和反射对我来说似乎不是一个好主意。

我正在考虑的是使用Assembly.CreateInstancefrom System.Reflection创建指定类的实例,但是由于这是我第一次处理此问题,因此我不知道是否有更好的方法可以做到这一点。这是有效的方法吗?

考虑到输入字符串将来自XML文件,有没有更简单的方法?也许我的问题已经在我缺少的某些.NET Assembly中得到了解决。

杰布

这是我想出的。通用工厂类,该类自动注册属于给定类型的子类的所有类型,并允许您通过它们的名称实例化它们。这与注释中@Achilles链接的Java SO问题中显示的方法有些相关,只是没有与该类型关联的初始化函数。

无需维护所有类型的枚举/开关组合。它也应该易于扩展,以处理您建议的基于反射的初始化。

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();
    }
}

假设问题的类别存在,您将实例化特定的汽车,如下所示:

var car = StringFactory<BaseCar>.Create("SportsCar");
DoSomethingWith(car.EngineID());

由于您的问题是要讨论最佳方法,因此请仅考虑其中一种。我没有在生产环境中使用过此方法,完全有可能针对您的特定情况使用了错误的方法。但是,它足以显示一般原理,并且应该为进一步的讨论提供起点。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章