请大家帮忙,我有这个案例。
switch(MyFoo()){
case 0: //...
break;
case 1: //...
break;
case 2: //...
break;
default:
// <HERE>
break;
}
如你所见,开关直接从一个方法中获取值,而没有将其保存为一个变量。
是否可以得到哪个值触发了 default
的情况下?例如如果 MyFoo()
返回7,怎样才能得到这个值?
我想避免把方法的结果保存为一个变量,有没有办法从case里面获取开关值?类似这样的。
default:
this.SwitchValue // <<--
break;
谢谢你的阅读,~Saba
有什么方法可以从case里面获取开关值吗?
唯一(正确)的方法实际上是将结果存储在 MyFoo()
在一个变量中。
var fooResult = MyFoo();
switch (fooResult)
{
case 0:
...
break;
...
default:
handleOthersCase(fooResult);
break;
}
这段代码是可读可懂的,而且没有额外的成本(正如@SheldonNeilson所说:反正它在栈上)。
另外,MSDN的第一个例子是关于 开关 完全是这个样子。你也可以找到信息在 语言规范.
你也可以自己做 开关 基于 词典但我看到的唯一优势是,你可以用它来处理复杂的 案件 任何一种对象而不是stringint...)。性能是一个缺点。
它可能看起来像这样。
public class MySwitch<T> : Dictionary<T, Action<T>>
{
private Action<T> _defaultAction;
public void TryInvoke(T value)
{
Action<T> action;
if (TryGetValue(value, out action))
{
action(value);
}
else
{
var defaultAction = _defaultAction;
if (defaultAction != null)
{
defaultAction(value);
}
}
}
public void SetDefault(Action<T> defaultAction)
{
_defaultAction = defaultAction;
}
}
然后像这样使用:
var mySwitch = new MySwitch<int>();
mySwitch.Add(1, i => Console.WriteLine("one")); // print "one"
mySwitch.Add(2, i => Console.WriteLine("two")); // print "two"
mySwitch.SetDefault(i => Console.WriteLine("With the digits: {0}", i)); // print any other value with digits.
mySwitch.TryInvoke(42); // Output: "With the digits: 42"
或者基于 此回答,这个。
public class MySwitch2<T>
{
private readonly T _input;
private bool _done = false;
private MySwitch2(T input)
{
_input = input;
}
public MySwitch2<T> On(T input)
{
return new MySwitch2<T>(input);
}
public MySwitch2<T> Case(T caseValue, Action<T> action)
{
if (!_done && Equals(_input, caseValue))
{
_done = true;
action(_input);
}
return this;
}
public void Default(Action<T> action)
{
if (!_done)
{
action(_input);
}
}
}
可以这样使用。
MySwitch2<int>.On(42)
.Case(1, i => Console.WriteLine("one"))
.Case(2, i => Console.WriteLine("two"))
.Default(i => Console.WriteLine("With the digits: {0}", i));
我也不知道为什么要这么用,但可能有一个变通的办法就是这样。
int x;
switch ( x = MyFoo())
{
case 0: //...
break;
case 1: //...
break;
case 2: //...
break;
default:
var s = x; // Access and play with x here
break;
}
不,这是不可能的,你可以把值赋给开关里面的变量,如果你想看起来像重新发明轮子的话。
int b;
.....
switch (b = MyFoo())
{
case 1:
break;
case 2:
break;
default:
//do smth with b
break;
}
最简单的方法是把结果保存在... MyFoo()
作为一个变量。但如果你不想这样做,你可以这样做。
switch(MyFoo()){
case 0: //...
break;
case 1: //...
break;
case 2: //...
break;
default:
this.SwitchCase = MyFoo();
break;
}
不过我建议你不要这样做 把值保存为一个变量 以节省你的程序的额外工作。
保存变量的值 MyFoo
作为一个变量,这个例子变得越复杂越重要,因为 MyFoo
可以在切换和默认情况下改变。
另外,这只适用于 MyFoo
没有任何副作用,而且对于任何给定的参数,显然必须总是返回相同的值。
例如,下面的代码可以用。
Private int MyFoo()
{
return 3;
}
但下面就不行了
private int MyFoo()
{
Random r = new Random();
return r.Next(5);
}