现在我有以下功能,对我来说并不是很好看:
string input = "??";
Letter output = null;
switch(input[0])
{
case LetterA.Id: // = 'A'
output = new LetterA();
break;
case LetterB.Id: // = 'B'
output = new LetterB();
break;
case LetterC.Id: // = 'C'
output = new LetterC();
break;
// ...
}
if (output == null)
throw new Exception();
output.Parse(input);
return output;
是否有更好/更短的方法来解决此问题并基于标识符创建类?
答案 0 :(得分:0)
你可以使用反射。以下假设Letter
,LetterA
,LetterB
等都存在于同一个程序集中。
var letterType = typeof(Letter).Assembly.GetTypes()
.Where(t => t.Name == "Letter" + input[0]);
var output = Activator.CreateInstance(letterType) as Letter;
请注意,如果无法找到类型或在实例化后无法转换为Letter
,则上面应添加一些错误检查。
答案 1 :(得分:0)
你得到的东西会起作用,而且并不少见。
另一种选择是创建一个字典,将Id字符串映射到一个委托,该委托返回一个Letter或字典,将Id映射到一个派生自Letter的对象,从中可以制作克隆(该选择可能取决于不同派生的Letter类是否具有不同的构造参数。)
//example of second
Dictionary<string, Letter> PrototypeLetters = new Dictionary<string, Letter>();
//...
output = PrototypeLetters[input]->MakeClone();
//where make clone is virtual in Letter returning a Letter (of derived type as Letter)
//still need to handle case where input is not found
在缺点方面,您必须构建该映射,如果您需要改变行为,则在运行时构建它会更灵活,但这包括引入错误的灵活性,并使单元测试变得不那么容易。
在正面,从Id获取信件的代码不必知道每个派生的Letter类型。
您是否认为该选项更好取决于您比较选项的标准。