C# - 如果在默认情况下获取开关值
C# - Get switch value if in default case
求助,我有这个案例:
switch(MyFoo()){
case 0: //...
break;
case 1: //...
break;
case 2: //...
break;
default:
// <HERE>
break;
}
如您所见,开关直接从方法中获取值,而不将其保存为变量。
是否有可能获得触发 default
案例的值?
例如,如果 MyFoo()
returns 7,我如何获得该值?
我想避免将方法结果保存为变量,有没有办法从案例中获取开关值?像这样:
default:
this.SwitchValue // <<--
break;
感谢您的阅读,
~萨巴
Is there a way to get the switch value from inside a case?
唯一(正确)的方法实际上是将 MyFoo()
的结果存储在变量中。
var fooResult = MyFoo();
switch (fooResult)
{
case 0:
...
break;
...
default:
handleOthersCase(fooResult);
break;
}
此代码可读易懂,没有额外成本(正如@SheldonNeilson 所说:无论如何它都在堆栈上)。
另外,关于switch totally look like this. You can also find informations int the language specification的MSDN第一个例子。
您也可以基于 dictionary 制作自己的 switch,但我看到的唯一优点是您可以将它用于复杂的 cases(任何类型的对象而不是 string/int/...)。性能是一个缺点。
它可能看起来像这样:
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"
或者基于this response,这个:
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));
最简单的方法是将 MyFoo()
的结果保存为变量。但是如果您不想这样做,您可以这样做:
switch(MyFoo()){
case 0: //...
break;
case 1: //...
break;
case 2: //...
break;
default:
this.SwitchCase = MyFoo();
break;
}
尽管我建议不要这样做,并建议将值保存为变量以节省程序的额外工作。
示例越复杂,将 MyFoo
的值保存为变量就变得越重要,因为 MyFoo
的值可能在 switch 和默认情况下发生变化。
此外,这仅在 MyFoo
没有副作用的情况下有效,并且显然必须始终 return 任何给定参数的相同值。
例如,以下内容可行:
Private int MyFoo()
{
return 3;
}
但以下不会:
private int MyFoo()
{
Random r = new Random();
return r.Next(5);
}
我也看不出为什么要那样使用它,但可能会像这样解决:
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;
}
现在这是可能的。
https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-8#property-patterns
示例:
int? TryGetColumnIndex(string columnName)
=> GetValue(columnName)
switch
{ var result when result > -1 => result, _ => new int?() };
result 将捕获 GetValue 的结果。
更酷的是,您可以进行 属性 检查。
即当结果 > -1 你甚至可以说当 result.ToString().Length > 2 等等。
求助,我有这个案例:
switch(MyFoo()){
case 0: //...
break;
case 1: //...
break;
case 2: //...
break;
default:
// <HERE>
break;
}
如您所见,开关直接从方法中获取值,而不将其保存为变量。
是否有可能获得触发 default
案例的值?
例如,如果 MyFoo()
returns 7,我如何获得该值?
我想避免将方法结果保存为变量,有没有办法从案例中获取开关值?像这样:
default:
this.SwitchValue // <<--
break;
感谢您的阅读, ~萨巴
Is there a way to get the switch value from inside a case?
唯一(正确)的方法实际上是将 MyFoo()
的结果存储在变量中。
var fooResult = MyFoo();
switch (fooResult)
{
case 0:
...
break;
...
default:
handleOthersCase(fooResult);
break;
}
此代码可读易懂,没有额外成本(正如@SheldonNeilson 所说:无论如何它都在堆栈上)。
另外,关于switch totally look like this. You can also find informations int the language specification的MSDN第一个例子。
您也可以基于 dictionary 制作自己的 switch,但我看到的唯一优点是您可以将它用于复杂的 cases(任何类型的对象而不是 string/int/...)。性能是一个缺点。
它可能看起来像这样:
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"
或者基于this response,这个:
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));
最简单的方法是将 MyFoo()
的结果保存为变量。但是如果您不想这样做,您可以这样做:
switch(MyFoo()){
case 0: //...
break;
case 1: //...
break;
case 2: //...
break;
default:
this.SwitchCase = MyFoo();
break;
}
尽管我建议不要这样做,并建议将值保存为变量以节省程序的额外工作。
示例越复杂,将 MyFoo
的值保存为变量就变得越重要,因为 MyFoo
的值可能在 switch 和默认情况下发生变化。
此外,这仅在 MyFoo
没有副作用的情况下有效,并且显然必须始终 return 任何给定参数的相同值。
例如,以下内容可行:
Private int MyFoo()
{
return 3;
}
但以下不会:
private int MyFoo()
{
Random r = new Random();
return r.Next(5);
}
我也看不出为什么要那样使用它,但可能会像这样解决:
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;
}
现在这是可能的。
https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-8#property-patterns
示例:
int? TryGetColumnIndex(string columnName)
=> GetValue(columnName)
switch
{ var result when result > -1 => result, _ => new int?() };
result 将捕获 GetValue 的结果。
更酷的是,您可以进行 属性 检查。
即当结果 > -1 你甚至可以说当 result.ToString().Length > 2 等等。