是否有可能用一些较短的可读代码编写下一个开关?
switch (SomeValue)
{
case "001": return DoMethod1(); break;
case "002": return DoMethod2(); break;
//etc..
}
我在想某种方式像
Dictionary<string, Func<int>> MethodsByValue = new Dictionary<string, Func<int>>()
{
{ "001", DoMethod1 },
{ "002", DoMethod2 },
}
并通过执行
来调用它return MethodsByValue[SomeValue]();
但这有可能吗?或者我是想远远超出开箱即用的。我找不到这样的东西,但话又说回来,如果可能,我不知道关键词。
编辑:回答Lasse V. Karlsen的要求:
这就是代码在我的项目中的方式。在某些地方更改名称会导致原始名称无关紧要,因为它是我母语。
public string GetRecord420(Dictionary<DataClass, object> dictionaryName)
{
// some code here
}
public string GetRecord421(Dictionary<DataClass, object> dictionaryName)
{
// some code here
}
//(Temperary) solution with the switch statement in a wrapper:
public string GetRecordByString(string s, Dictionary<DataClass, object> dictionaryName)
{
switch (s)
{
case "320": return GetRecord420(dictionaryName);
case "321": return GetRecord421(dictionaryName);
default: return String.Empty;
}
}
//How I hoped it could be, with a mapping dictionary.
public Dictionary<string, Func<string, Dictionary<DataClass, object>>> MethodByString =
new Dictionary<string, Func<string, Dictionary<DataClass, object>>>()
{
{ "320", GetRecord420 },
{ "321", GetRecord421 },
}
DataClass是一个Entity类,它存储一些列数据(列名,列类型等)。
我尝试了字典部分,但它给了我错误:无法从方法组转换为System.Func&lt; ...&gt;。
更改为()=&gt; GetRecord420给出了错误:无法将lambda转换为委托类型System.Func&lt; ...&gt;因为块中的某些返回类型不能隐式转换为委托返回类型。
答案 0 :(得分:0)
方法定义必定存在错误,
class Program
{
static void Main()
{
var methods = new Dictionary<string, Func<int>>
{
{ "001", DoMethod1 }
};
}
static int DoMethod1()
{
return 1;
}
}
是完全有效的语法。
但是,对于1个引人注目的主观原因,这并不比switch
好。
如果要与常量或文字进行比较,则应使用switch。这使编译器无需额外分析即可执行编译时优化。
更主观地说,字典/查找方法并不短,我发现它更难阅读。但是,在比较术语在运行时变化的情况下,它会很有用。
如果您想避免将switch
因素重写为函数。说,
Func<int> MethodsByValue(string value)
{
switch(value)
{
case "001":
return DoMethod1;
default:
return DoMethod2;
}
}
无论哪种方式,
为什么不使用enum
而不是使用一些arbritary字符串来枚举你的方法?然后,您将获得额外的性能和可读性优势。
答案 1 :(得分:0)
您可以通过删除多余的break
来缩短您拥有的内容,如果发生两种情况应该调用相同的方法,那么您可以通过:
switch (SomeValue) {
case "001": return DoMethod1();
case "002": return DoMethod2();
case "003":
case "004": return DoMethod34();
//etc..
}
至于你的伪建议,以及提倡它的另一个答案,我不知道这是多么简短或更简洁。但是,在使用中可以减少代码并清楚,例如:
Func<int> GetMethod(string key) {
return MethodsByValue[key];
}
Func<int> method = GetMethod("001");
method();
答案 2 :(得分:0)
一般来说,切换的一个好选择是使用State Design Pattern其他好的选择是Strategy Pattern。它将使您的代码更具可扩展性,并且更加面向对象。
答案 3 :(得分:0)
我使用了Mapping extension。这样您就可以使用以下语法:
return SomeValue
.Map("001", DoMethod1)
.Map("002", DoMethod2)
//etc
这使得它也可以这样做:
return SomeValue
.Map(1, DoMethod1)
.Map(2, DoMethod2)
.Map(x => x < 0, DoMethod3)
.Map(x => x > 5 && x < 10, DoMethod4)
.Else(4); // a simple value of a method