例如
if (x=="A)
switch (y)
{
case "1": Do1();break;
case "2": Do2();break;
case "3": Do3();break;
}
else if (x=="B")
switch (y)
{
case "1": Do4();break;
case "2": Do5();break;
case "3": Do6();break;
}
else
switch (y)
{
case "1": Do7();break;
case "2": Do8();break;
case "3": Do9();break;
}
我希望我可以执行以下操作,但它有许多冗余检查。
if (x=="A" && y=="1")
Do1();
else if (x=="A" && y=="2")
Do2();
else if (x=="A" && y=="3")
Do3();
else if (x=="B" && y=="1")
Do4();
else if (x=="B" && y=="2")
Do5();
else if (x=="B" && y=="3")
Do6();
else if (x=="C" && y=="1")
Do7();
else if (x=="C" && y=="2")
Do8();
else if (x=="C" && y=="3")
Do9();
答案 0 :(得分:2)
介绍OOPS的建议真的很棒,请不要忽视该评论。你可以暂时编写这样的代码。
var combinedText = x+y;
switch(combinedText)
{
case "A1": Do1(); break;
case "A2": Do2(); break;
case "A3": Do3(); break;
case "B1": Do4(); break;
case "B2": Do5(); break;
case "B3": Do6(); break;
case "C1": Do7(); break;
case "C2": Do8(); break;
case "C3": Do9(); break;
}
答案 1 :(得分:1)
void Main()
{
Dictionary<string, Action> d = new Dictionary<string, Action>()
{
{"A1", Do1},
{"A2", Do2},
{"A3", Do3},
{"B1", Do4},
{"B2", Do5},
{"B3", Do6},
{"1", Do7},
{"2", Do8},
{"3", Do9}
};
var x = "A";
var y = "1";
var action = x == "A" || x == "B" ? x + y : y;
if (d.ContainsKey(action))
d[action]();
}
public void Do1() {}
public void Do2() {}
public void Do3() {}
public void Do4() {}
public void Do5() {}
public void Do6() {}
public void Do7() {}
public void Do8() {}
public void Do9() {}
修改强>
我记得这个fluent functional switch:
var sw = new Switch<string>(action)
.Case("A1", s => Do1())
.Case("A2", s => Do2());
答案 2 :(得分:1)
您的代码目前有两个职责 - 决定执行哪些方法(变量x)并决定执行哪个确切方法(变量y)。使代码更加清晰的最简单选项 - 拆分此职责并提取方法,这将决定调用方法集中的哪种方法
switch (x)
{
case "A": DoA(y); break;
case "B": DoB(y); break;
default:
DoDefault(y); break;
}
现在您的来电者代码很简单。这是DoX方法之一:
private void DoA(string y)
{
switch (y)
{
case "1": Do1(); break;
case "2": Do2(); break;
case "3": Do3(); break;
}
}
其他选项是使用.net来决定使用多态来调用哪组方法。但是在只有一个开关(x)块的简单情况下,我不建议这样做。如果您的实际代码更复杂,那么考虑提取将保存一组功能(Do1,Do2,Do3)的类,并决定该功能的执行。例如。调用代码:
IDo ido = CreateIDo(x);
ido.Do(y);
是的,就是这样。非常干净。这是IDo界面创建代码:
public static IDo CreateIDo(string x)
{
switch (x)
{
case "A": return new A();
case "B": return new B();
default:
return new C();
}
}
这里是A类,它在执行它们时封装了第一组方法和决策:
public interface IDo
{
void Do(string y);
}
public class A : IDo
{
public void Do(string y)
{
switch (y)
{
case "1": Do1(); break;
case "2": Do2(); break;
case "3": Do3(); break;
}
}
private void Do1() { }
private void Do2() { }
private void Do3() { }
}
再次使用它,以防你的真实代码更复杂。
答案 3 :(得分:1)
我会使用IEnumerable的元组集合和Action delegate来定义要调用的方法列表,将列表创建为私有字段或类初始化器,或者要灵活地添加元组到根据需要提供公共财产。如果需要传入参数,请使用Action委托的一个重载版本,即:Action(t1,t2)等。
如果您需要返回值,请根据其他答案使用Func delegate。
IEnumerable<Tuple<string, string, Action>> actions = new List<Tuple<string, string, Action>>() {
Tuple.Create<string, string, Action>("A", "1", SomeMethod1),
Tuple.Create<string, string, Action>("A", "2", SomeMethod2)
};
string x = "A";
string y = "2";
var action = actions.FirstOrDefault(t => ((t.Item1 == x) && (t.Item2 == y)));
if (action != null)
action.Item3();
else
DoSomeDefaultMethod();
public void SomeMethod1() { // Whatever you want to do }
public void SomeMethod2() { // Whatever you want to do }
public void DoSomeDefaultMethod() { // Default Method }
答案 4 :(得分:0)
如果您不想更改当前结构的大部分内容(并且不想创建新类型等),请考虑这一点。
将它们添加到下面的元组
var tuples = new List<Tuple<string,string,Func<>>()>(); // Func should be of your Do() type
将带有相关func的条件数据添加到列表
tuples.Add(new Tuple<string,string,Func<>>("A","1", Do1()));
...
只需在需要时使用条件直接调用
var function = tuples.Where(x => x.item1 == "A" && x.item2 == "1").Select(x => x.item3);
function.Invoke(); // to call it.
现在,如果您将来有更多的条件,您只需将它们添加到列表中,而无需更改任何代码。
答案 5 :(得分:0)
使用这样的东西。如果愿意,只有三个。
if (x == "A")
{
int a = (y == "1") ? do1() : ((y == "2") ? do2() : do3());
}
}
int do1() { return 10; }
int do2() { return 10; }
int do3() { return 10; }
答案 6 :(得分:-1)
我想在代码中的多个位置执行相同类型的开关,如果这样,请重构它并使用polymorphism instead
如果X是字符串优先replace the typecode with class并使用多态。