在System.Linq.Expressions中切换时不使用大小写(但使用默认设置)

维亚切斯拉夫·伊万诺夫(Viacheslav Ivanov)

我试图用System.Linq.Expressions创建一个开关表达式:

var value = Expression.Parameter(typeof(int));
var defaultBody = Expression.Constant(0);
var cases1 = new[] { Expression.SwitchCase(Expression.Constant(1), Expression.Constant(1)), };
var cases2 = new SwitchCase[0];
var switch1 = Expression.Switch(value, defaultBody, cases1);
var switch2 = Expression.Switch(value, defaultBody, cases2);

但在最后一行中,我得到了ArgumentException:

需要非空收集。参数名称:案例

发生此异常的原因是什么?这可能是Expression.Switch(...)中的错误吗?

在C#中,仅具有“默认”部分的开关是正确的:

switch(expr) {
default:
  return 0;
}//switch

UPD:我已向GitHub上的CoreFX存储库提交了一个问题

乔恩·汉纳

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)); // Zero
Console.WriteLine(meth(1)); // One
Console.WriteLine(meth(2)); // 2

在这里,SwitchExpression返回值是switch做不到的。

因此,就像可以做某事SwitchExpression并不意味着您可以用做某事switch,因此也没有理由假设可以用某事做某事而switch您可以对做某事SwitchExpression

就是说,我认为没有理由SwitchExpression设置这种方式,除了它可以简化表达式没有大小写没有默认主体的情况。就是说,我认为这可能只是表达通常要包含多个案例的问题,而这正是它被编码为支持的内容。

我已经向.NET Core提交了一个pull-request请求,请求将通过生成一个SwitchExpressionwhere类型的默认值switchValue与默认主体相同的主体,从而允许这种不分大小写的表达式这种方法意味着SwitchExpression没有案例的情况下,任何令人惊讶的事情都应该解决,避免了向后兼容的问题。通过创建不执行任何操作的noop表达式来处理没有默认值的情况,因此,现在仍然抛出一个唯一的情况ArgumentException是,如果没有大小写没有默认值并且类型明确设置为void,在明显必须保留的打字规则下,这种情况无效。

[更新:该方法已被拒绝,但后来的请求请求被接受,因此SwitchExpression.NET Core现在允许使用不区分大小写的,尽管其他版本的.NET是否以及何时采用它是另一回事]。

同时,或者如果您使用其他版本的.NET,则最好使用以下帮助方法:

public static Expression SwitchOrDefault(Type type, Expression switchValue, Expression defaultBody, MethodInfo comparison, IEnumerable<SwitchCase> cases)
{
  if (cases != null)
  {
    // It's possible that cases is a type that can only be enumerated once.
    // so we check for the most obvious condition where that isn't true
    // and otherwise create a ReadOnlyCollection. ReadOnlyCollection is
    // chosen because it's the most efficient within Switch itself.
    if (!(cases is ICollection<SwitchCase>))
      cases = new ReadOnlyCollection<SwitchCase>(cases);
    if (cases.Any())
      return Switch(type, switchValue, defaultBody, comparison, cases);
  }
  return Expression.Block(
    switchValue, // include in case of side-effects.
    defaultBody != null ? defaultBody : Expression.Empty() // replace null with a noop expression.
  );
}

重载如下:

public static Expression SwitchOrDefault(Expression switchValue, Expression defaultBody, params SwitchCase[] cases)
{
  return SwitchOrDefault(switchValue, defaultBody, null, (IEnumerable<SwitchCase>)cases);
}

然后可以添加等等。

Expression比我的pull-request总体上要更整齐,因为它switch在没有大小写的情况下完全切掉了,只返回默认主体。如果确实需要a,SwitchExpression则可以创建类似的帮助程序方法,该方法遵循与pull-request在创建新的SwitchCase然后使用它时所做的逻辑相同的逻辑

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何使用System.Dynamic.Linq对大小写不敏感进行排序?

来自分类Dev

System.Linq.Expressions 与计算列

来自分类Dev

使用System.Linq占用多少空间?

来自分类Dev

如何使用System.Linq.Expressions API模拟“ typeof(T)”?

来自分类Dev

无法从“ System.Linq.Expressions.LambdaExpression”转换为“ System.Linq.Expressions.Expression”

来自分类Dev

如何从System.Linq.Expressions.Expression中删除括号?

来自分类Dev

如何从System.Linq.Expressions.Expression中删除括号?

来自分类Dev

获取 System.Linq.Expressions.Expression 对象的类型

来自分类Dev

如何使用Linq进行区分大小写

来自分类Dev

如何使用Linq进行区分大小写

来自分类Dev

System.NotSupportedException使用DateTime吗?在Linq to实体

来自分类Dev

在IEnumerable <t>的情况下使用System.Linq?

来自分类Dev

无法使用System.Linq.Dynamic进行排序

来自分类Dev

使用反射调用OrderBy(System.Linq.Enumerable)

来自分类Dev

如何使用System.Xml.Linq解析xml文件

来自分类Dev

C ++ / CLI并使用System :: Linq无法正常工作

来自分类Dev

System.Linq.Expressions.ExpressionVisitor.VisitExtension和System.Linq.Expressions.ExpressionType.Extension的作用是什么?

来自分类Dev

是否可以在不包含System.Linq命名空间的情况下使用Linq和lambdas?

来自分类Dev

使用System.Linq.Expressions API重写Lambda表达式

来自分类Dev

我可以使用System.Linq.Expressions动态生成异步方法吗?

来自分类Dev

'EntityFramework.Core,版本= 7.0.0.0,使用'System.Linq.Expressions,版本= 4.0.11.0

来自分类Dev

将SQL Server ROWVERSION放入System.Data.Linq.Binary属性时出现System.InvalidCastException

来自分类Dev

使SQL Server ROWVERSION进入System.Data.Linq.Binary属性时出现System.InvalidCastException

来自分类Dev

在数据绑定中切换大小写

来自分类Dev

在C中切换大小写帮助

来自分类Dev

在JavaScript函数中切换大小写

来自分类Dev

在Codeignitner中切换大小写

来自分类Dev

在 Python 中切换大小写

来自分类Dev

使用SwiftLint切换大小写格式问题

Related 相关文章

  1. 1

    如何使用System.Dynamic.Linq对大小写不敏感进行排序?

  2. 2

    System.Linq.Expressions 与计算列

  3. 3

    使用System.Linq占用多少空间?

  4. 4

    如何使用System.Linq.Expressions API模拟“ typeof(T)”?

  5. 5

    无法从“ System.Linq.Expressions.LambdaExpression”转换为“ System.Linq.Expressions.Expression”

  6. 6

    如何从System.Linq.Expressions.Expression中删除括号?

  7. 7

    如何从System.Linq.Expressions.Expression中删除括号?

  8. 8

    获取 System.Linq.Expressions.Expression 对象的类型

  9. 9

    如何使用Linq进行区分大小写

  10. 10

    如何使用Linq进行区分大小写

  11. 11

    System.NotSupportedException使用DateTime吗?在Linq to实体

  12. 12

    在IEnumerable <t>的情况下使用System.Linq?

  13. 13

    无法使用System.Linq.Dynamic进行排序

  14. 14

    使用反射调用OrderBy(System.Linq.Enumerable)

  15. 15

    如何使用System.Xml.Linq解析xml文件

  16. 16

    C ++ / CLI并使用System :: Linq无法正常工作

  17. 17

    System.Linq.Expressions.ExpressionVisitor.VisitExtension和System.Linq.Expressions.ExpressionType.Extension的作用是什么?

  18. 18

    是否可以在不包含System.Linq命名空间的情况下使用Linq和lambdas?

  19. 19

    使用System.Linq.Expressions API重写Lambda表达式

  20. 20

    我可以使用System.Linq.Expressions动态生成异步方法吗?

  21. 21

    'EntityFramework.Core,版本= 7.0.0.0,使用'System.Linq.Expressions,版本= 4.0.11.0

  22. 22

    将SQL Server ROWVERSION放入System.Data.Linq.Binary属性时出现System.InvalidCastException

  23. 23

    使SQL Server ROWVERSION进入System.Data.Linq.Binary属性时出现System.InvalidCastException

  24. 24

    在数据绑定中切换大小写

  25. 25

    在C中切换大小写帮助

  26. 26

    在JavaScript函数中切换大小写

  27. 27

    在Codeignitner中切换大小写

  28. 28

    在 Python 中切换大小写

  29. 29

    使用SwiftLint切换大小写格式问题

热门标签

归档