C# 如何用字典替换此开关盒<;字符串,Func<&燃气轮机>;?
我讨厌开关箱。我试图在我的代码中重构一个switch-case,如下所示:C# 如何用字典替换此开关盒<;字符串,Func<&燃气轮机>;?,c#,refactoring,func,C#,Refactoring,Func,我讨厌开关箱。我试图在我的代码中重构一个switch-case,如下所示: int i = 0; string str = string.empty; switch (color) { case "red": i = MyIntArgsFunction(1, 2); case "blue": str = MyStringArgsFunction("cat", "dog"); } private int MyIntArgsFunction(i
int i = 0;
string str = string.empty;
switch (color)
{
case "red":
i = MyIntArgsFunction(1, 2);
case "blue":
str = MyStringArgsFunction("cat", "dog");
}
private int MyIntArgsFunction(int x, int y)
{
// Implementation
}
private string MyStringArgsFunction(string s, string t)
{
// Implementation
}
我想将两个函数MyIntArgsFunction和MyStringArggsFunction添加到Dictionary>结构中,然后根据用户选择的颜色调用相应的函数。但是由于参数的不同,我无法为Func委托找到合适的签名
有人能帮忙吗
尼哈尔它看起来像地狱,但它是有效的:)
private static void Main(字符串[]args)
{
var blueHandler=新操作((x,y)=>{});
var redHandler=新操作((x,y)=>{Console.WriteLine(x);});
var redStr=“Red”;
var blueStr=“蓝色”;
var colorSelector=新字典();
var a=10;
var b=20;
Add(redStr,新调用程序(redHandler,a,b));
Add(blueStr,新调用程序(blueHandler,a,b));
颜色选择器[“红色”]。调用();
}
公共类调用程序
{
私有委托处理程序;
公共对象[]参数;
公共调用程序(委托处理程序,参数对象[]参数)
{
_param=param;
_handler=handler;
}
公共无效调用()
{
_handler.DynamicInvoke(_参数);
}
}
一位学者会建议采用“面向对象”的方法。
遗憾的是,工厂模式需要一个开关箱,您的客户表示您“讨厌开关箱”,但最好也说明具体原因。
我想这都是关于代码清晰性和“案例”插件可用性的
这是我避免开关箱的方法
public abstract class ColorHandler
{
public String str { get; set; }
public int i { get; set; }
public abstract void Handle();
public static ColorHandler ColorHandlerFactory(String color,ref int i, ref string str)
{
ColorHandler handler = Handlers[color];
handler.i = i;
handler.str = str;
handler.Handle();
return handler;
}
public static Dictionary<String, ColorHandler> Handlers = new Dictionary<string, ColorHandler> ()
{
{"red",new RedHandler{myInt1 = 1,myInt2 =2,}},
{"blue",new BlueHandler{MyStr1="str1",MyStr2="str2"} }
};
public Dictionary<String, ColorHandler> InitHandlers(int myNum1,int myNum2,string myStr1,string myStr2){
return new Dictionary<string, ColorHandler>()
{
{"red",new RedHandler{myInt1 = myNum1,myInt2 =myNum2}},
{"blue",new BlueHandler{MyStr1=myStr1,MyStr2=myStr2} }
};
}
}
public class RedHandler : ColorHandler
{
public int myInt1 { get; set; }
public int myInt2 { get; set; }
public override void Handle()
{
this.i = myInt1+myInt2;
// OR alternatively
//this.myInt1 = AnExternalFunction(myInt1, myInt2);
}
}
public class BlueHandler : ColorHandler
{
public String MyStr1 { get; set; }
public String MyStr2 { get; set; }
public override void Handle()
{
this.str = MyStr1 + MyStr2;
// OR alternatively
//this.myInt1 = AnExternalFunction(MyStr1, MyStr2);
}
}
public class Doer
{
public void DoThings()
{
int i = 0;
string str = string.Empty;
var handler =ColorHandler.ColorHandlerFactory("red",ref i,ref str);
handler.InitHandlers(1, 2, "Cat", "Dog");
//Read Results.
var result=handler.i;
}
}
公共抽象类ColorHandler
{
公共字符串str{get;set;}
公共整数i{get;set;}
公共抽象无效句柄();
公共静态ColorHandler ColorHandlerFactory(字符串颜色、ref int i、ref String str)
{
ColorHandler=处理程序[颜色];
handler.i=i;
handler.str=str;
Handle.Handle();
返回处理程序;
}
公共静态字典处理程序=新字典()
{
{“red”,新的RedHandler{myInt1=1,myInt2=2,},
{“蓝色”,新的BlueHandler{MyStr1=“str1”,MyStr2=“str2”}
};
公共字典InitHandlers(int myNum1、int myNum2、字符串myStr1、字符串myStr2){
返回新字典()
{
{“red”,新的RedHandler{myInt1=myNum1,myInt2=myNum2},
{“蓝色”,新的BlueHandler{MyStr1=MyStr1,MyStr2=MyStr2}
};
}
}
公共类RedHandler:ColorHandler
{
公共int myInt1{get;set;}
公共int myInt2{get;set;}
公共重写无效句柄()
{
i=myInt1+myInt2;
//或者
//this.myInt1=AnExternalFunction(myInt1,myInt2);
}
}
公共类BlueHandler:ColorHandler
{
公共字符串MyStr1{get;set;}
公共字符串MyStr2{get;set;}
公共重写无效句柄()
{
this.str=MyStr1+MyStr2;
//或者
//this.myInt1=AnExternalFunction(MyStr1,MyStr2);
}
}
公共类实干家
{
公共无效DoThings()
{
int i=0;
string str=string.Empty;
var handler=ColorHandler.ColorHandlerFactory(“红色”,参考i,参考str);
handler.InitHandlers(1,2,“猫”,“狗”);
//阅读结果。
var result=handler.i;
}
}
您还可以改变结构以支持批处理。
处理程序是值的默认初始化。
InitHandler是一个函数,用于覆盖这些值。
作者Chris Brandsma提供了另一种使用基于词典的工厂的有用方法。还要注意Henrik Gustafsson的评论,这提供了一种实现工厂的多态方法
据Henrik Gustafsson称:
switch语句通常可以被多态性的仔细应用所取代。如果重构使switch语句是方法中的唯一内容,并且switch语句中的每个条目只调用另一个方法,那么每个案例和每个方法的状态通常可以分组到其自己的子类中。作为奖励,您可以降低圈复杂度,为什么要创建一个委托呢?需要什么?你能解释一下或者展示一下你想要达到的目标吗?作为
对象传递并施放。不,这根本不是一个好的建议。看起来您可能需要两个字典:一个用于integer
函数,另一个用于string
one我想他只是想摆脱开关盒来实现这一点:myFuncDict[color](myArg1,myArg2)代码>谢谢,朋友,我喜欢你的解决方案!这符合你的要求吗?@Mitklantekuli是的,你给了我一个实施的想法!非常感谢。我强烈建议调整缩进以提高代码的可读性
public abstract class ColorHandler
{
public String str { get; set; }
public int i { get; set; }
public abstract void Handle();
public static ColorHandler ColorHandlerFactory(String color,ref int i, ref string str)
{
ColorHandler handler = Handlers[color];
handler.i = i;
handler.str = str;
handler.Handle();
return handler;
}
public static Dictionary<String, ColorHandler> Handlers = new Dictionary<string, ColorHandler> ()
{
{"red",new RedHandler{myInt1 = 1,myInt2 =2,}},
{"blue",new BlueHandler{MyStr1="str1",MyStr2="str2"} }
};
public Dictionary<String, ColorHandler> InitHandlers(int myNum1,int myNum2,string myStr1,string myStr2){
return new Dictionary<string, ColorHandler>()
{
{"red",new RedHandler{myInt1 = myNum1,myInt2 =myNum2}},
{"blue",new BlueHandler{MyStr1=myStr1,MyStr2=myStr2} }
};
}
}
public class RedHandler : ColorHandler
{
public int myInt1 { get; set; }
public int myInt2 { get; set; }
public override void Handle()
{
this.i = myInt1+myInt2;
// OR alternatively
//this.myInt1 = AnExternalFunction(myInt1, myInt2);
}
}
public class BlueHandler : ColorHandler
{
public String MyStr1 { get; set; }
public String MyStr2 { get; set; }
public override void Handle()
{
this.str = MyStr1 + MyStr2;
// OR alternatively
//this.myInt1 = AnExternalFunction(MyStr1, MyStr2);
}
}
public class Doer
{
public void DoThings()
{
int i = 0;
string str = string.Empty;
var handler =ColorHandler.ColorHandlerFactory("red",ref i,ref str);
handler.InitHandlers(1, 2, "Cat", "Dog");
//Read Results.
var result=handler.i;
}
}