我目前有一个探测器接口,称为“模型”。在我的工厂类中,我有一个名为CreateDetector的函数,它返回适当的探测器模型。
public Detector CreateDetector(string modelName, string ip, string port) {
if ( modelName = "A" )
{
return new ModelA(ip, port);
}
if ( modelName = "B" )
{
return new ModelB(ip, port);
}
...
}
对我来说,这似乎效率很低,代码重复多次。在类似的情况下,我通常会使用以下方法。
public Detector CreateDetector(string modelName, string ip, string port) {
Dictionary<string, Detector> detectors = new Dictionary<string, Detector>()
{
{ "A", new ModelA(ip, port) },
{ "B", new ModelB(ip, port) },
...
};
return detectors[modelName]
}
但是,在Detector的当前实现中,基本构造函数始终调用Init(),它尝试连接到设备。显然,我不想将X次连接到设备,因为这可能会导致很多问题。 (这部分让我问这个问题,我理解构造函数不应该很重,但这是遗留代码,不会改变。)
我希望最终结果模拟这样的东西,其中字典只包含对象的声明,但只有在确定您正在使用哪个类时才会调用构造函数。
public Detector CreateDetector(string modelName, string ip, string port) {
Dictionary<string, Detector> detectors = new Dictionary<string, Detector>()
{
{ "A", ModelA(ip, port) },
{ "B", ModelB(ip, port) },
{ "C", ModelC(ip, port) },
...
{ "X", ModelX(ip, port) },
};
if (modelName = "B" || modelName = "C")
{
//special case for these 2 models
}
return new detectors[modelName]
}
我想要完成的是停止重复的“if / else”,这些都是相同的,但是在我请求它的值之前没有构造函数的初始化。
答案 0 :(得分:3)
我的班级中会有以下静态字段:
static Dictionary<string, Func<string, string, Detector>> _detectors = new Dictionary<string, Func<string, string, Detector>>()
{
{ "A", (ip, port)=> new ModelA(ip, port) },
{ "B", (ip, port)=> new ModelB(ip, port) }
};
字典的值是对象工厂方法:
var factory = _detectors[modelName]; // returned type is Func<string, string, Detector>
var result = factory(ip, port);
答案 1 :(得分:3)
您似乎正在寻找 Reflection ,如下所示:
using System.Reflection;
...
//DONE: do not recreate the dictionary, but create it once as a static field
static Dictionary<string, Detector> detectors = new Dictionary<string, Detector>() {
{ "A", typeof(ModelA) },
{ "B", typeof(ModelB) },
...
};
public Detector CreateDetector(string modelName, string ip, string port) {
//TODO: validate modelName
return detectors[modelName]
.GetConstructor(new Type[] {typeof(string), typeof(string)})
.Invoke(new object[] {ip, port}) as Detector;
}
如果型号&#39;名称是常规(例如,类名是"Model" + modelName
)你可以更进一步:删除字典并尝试搜索模型的类型
using System.Linq;
using System.Reflection;
...
public Detector CreateDetector(string modelName, string ip, string port) {
//TODO: validate modelName
Type modelType = Assembly
.GetExecutingAssembly() //TODO: check the assembly
.GetTypes()
.Where(t => t.Name == "Model" + modelName)
.FirstOrDefault();
if (null == modelType)
return null; // Not found; you may want to throw exception here
return modelType
.GetConstructor(new Type[] {typeof(string), typeof(string)})
.Invoke(new object[] {ip, port}) as Detector;
}