我有一个通用的基础抽象类:
public abstract class Generator<T>
{
public abstract void Start(T config);
}
然后,我有许多从基类继承的具体类,并期望某些参数类型。其中一些:
public class AGenerator : Generator<AGeneratorConfig>
{
public override void Start(AGeneratorConfig Config) { /* some code*/ }
}
public class BGenerator : Generator<BGeneratorConfig>
{
public override void Start(BGeneratorConfig Config) { /* some code*/ }
}
他们的Start()
方法参数定义如下:
public abstract class GeneratorConfig
{
public int CommonProperty {get; set;}
}
public class AGeneratorConfig : GeneratorConfig
{
// Some props specific for AGenerator
}
public class BGeneratorConfig : GeneratorConfig
{
// Some props specific for BGenerator
}
最后,我有一个客户端/经理/工厂类,用提供的配置处理实际的生成器启动过程, 但是使用铸造混凝土来抽象泛类:
public class GeneratorClient
{
public static void StartGenerator<T>(T config)
{
Generator<T> generator = null;
if (config is AGeneratorConfig)
{
generator = new AGenerator() as Generator<T>; // casting to abstract base class
}
else if (config is BGeneratorConfig)
{
generator = new BGenerator() as Generator<T>; // casting to abstract base class
}
else
{
throw new NotImplementedException();
}
generator.Start(config);
}
}
我的问题:是否有任何解决方法可以消除将具体方法转换为抽象基类的需要?
最简单的解决方案是:
public static void StartGenerator<T>(T config)
{
if (config is AGeneratorConfig)
{
var generator = new AGenerator();
generator.Start(config);
}
else if (config is BGeneratorConfig)
{
var generator = new BGenerator();
generator.Start(config);
}
else
{
throw new NotImplementedException();
}
}
但是对于每个新创建的具体生成器,对象generator.Start(config);
需要重复。
答案 0 :(得分:2)
将generator
定义为object
,并仅在最后一次通话时将其投放到Generator<T>
:
public static void StartGenerator<T>(T config)
{
object generator = null;
if (config is AGeneratorConfig)
{
generator = new AGenerator();
}
else if (config is BGeneratorConfig)
{
generator = new BGenerator();
}
else
{
throw new NotImplementedException();
}
((Generator<T>)generator).Start(config);
}
答案 1 :(得分:1)
您可以使用Reflection来调用构造函数,也可以改进Factory,以便删除那些if。
您可以使用这样的词典:
private Dictionary<Type, Type> Diccionary;
public void CreateDicionary()
{
Diccionary = new Dictionary<Type, Type>();
Diccionary.Add(typeof(AGeneratorConfig), typeof(AGenerator));
Diccionary.Add(typeof(BGeneratorConfig), typeof(BGenerator));
}
然后你可以使用这样的具体实例:
public Generator<T> GetGenerator<T>()
{
var type = typeof(T);
if (!Diccionary.ContainsKey(type))
throw new Exception("Not found");
var typeInstance = Diccionary[type];
return (Generator<T>) Activator.CreateInstance(typeInstance);
}
您使用上面的代码与此类似:
public void StartGenerator<T>(T config)
{
var generator = GetGenerator<T>();
generator.Start(config);
}
public static void Main()
{
var gen = new GeneratorClient();
gen.CreateDicionary();
gen.StartGenerator<AGeneratorConfig>(new AGeneratorConfig());
}