C#的switch
和SwitchExpression
之间没有完全的类比。从另一个方向考虑,您可以有:
var value = Expression.Parameter(typeof(int));
var meth = Expression.Lambda<Func<int, string>>(
Expression.Switch(
value,
Expression.Call(value, typeof(object).GetMethod("ToString")),
Expression.SwitchCase(Expression.Constant("Zero"), Expression.Constant(0, typeof(int))),
Expression.SwitchCase(Expression.Constant("One"), Expression.Constant(1, typeof(int)))),
value
).Compile();
Console.WriteLine(meth(0));
Console.WriteLine(meth(1));
Console.WriteLine(meth(2));
这里的SwitchExpression
返回一个值,而switch
不能这样做。
因此,仅仅能够使用SwitchExpression
并不意味着你可以使用switch
来实现同样的功能,同样地,仅仅能够使用switch
也并不意味着你可以使用SwitchExpression
。
话虽如此,我认为没有很好的理由将SwitchExpression
设置成这样,除非是为了简化表达式没有case和默认体的情况。但是,我认为这可能只是表达式通常被设计用于具有多个case,并且被编码以支持这一点。
我
提交了一个.NET Core的pull-request, 该请求将允许这种无大小写表达式,通过生成一个
SwitchExpression
,其中
switchValue
类型的默认值具有与默认体相同的内容来实现。这种方法意味着任何对于没有case的
SwitchExpression
会感到惊讶的事情仍然可以处理,避免了向后兼容性问题。如果没有默认值,则创建一个不执行任何操作的noop表达式来处理,因此现在仅在没有case
和没有default
且类型明确设置为
void
以外的其他值的情况下仍会抛出
ArgumentException
,这种情况在必须显然保留的类型规则下无效。
[更新:该方法被拒绝,但
稍后的pull-request已被接受,因此.NET Core现在允许无case的
SwitchExpression
, 但是是否被其他版本的.NET采用是另一回事]。
同时,如果您使用的是其他版本的.NET,则最好使用像这样的辅助方法:
public static Expression SwitchOrDefault(Type type, Expression switchValue, Expression defaultBody, MethodInfo comparison, IEnumerable<SwitchCase> cases)
{
if (cases != null)
{
if (!(cases is ICollection<SwitchCase>))
cases = new ReadOnlyCollection<SwitchCase>(cases);
if (cases.Any())
return Switch(type, switchValue, defaultBody, comparison, cases);
}
return Expression.Block(
switchValue,
defaultBody != null ? defaultBody : Expression.Empty()
);
}
如下所示的重载:
public static Expression SwitchOrDefault(Expression switchValue, Expression defaultBody, params SwitchCase[] cases)
{
return SwitchOrDefault(switchValue, defaultBody, null, (IEnumerable<SwitchCase>)cases);
}
然后可以添加等等。
这将导致比我的拉取请求更简洁的Expression
,因为它完全削减了在无情况的情况下的switch
并只返回默认体。如果您确实需要一个SwitchExpression
,那么您可以创建一个类似的帮助方法,遵循与该拉取请求相同的逻辑来创建新的SwitchCase
,然后使用它。
default
但没有case
的switch
语句将只执行default
。 - Dmitry BychenkoSwitchCase
取决于某些条件,则无需特殊处理其为零的情况。 - Jon Hanna