【问题标题】:Why is it not allowed to declare empty expression body for methods?为什么不允许为方法声明空的表达式主体?
【发布时间】:2017-09-04 22:06:29
【问题描述】:

我有一个方法,它的主体是这样的:

public void Foo()
{
}

根据 ReSharper 的建议,我想将其转换为表达式主体以节省一些空间,结果变成:

public void Foo() => ;

无法编译。是否有不支持的具体原因?

我认为我应该为 ReSharper 开一个错误票,因为它会将代码重构为不可编译的版本。

【问题讨论】:

  • 是的,这是一个更清晰的错误。如果你想节省空间,那么public void Foo() {}(全是一行)实际上更短。
  • 我无法从这里访问 C# 规范,但可以从 here 访问:对于返回 void 的方法 - 和返回任务的异步方法 - 箭头语法仍然适用,但是箭头后面的表达式必须是语句表达式(就像 lambdas 的规则一样) 所以是的,一个 R# 错误
  • 也发现了这一点,C# 规范的第 7.1 节说 分类为无的表达式仅在语句表达式的上下文中有效。 所以你需要在那里。例如,您可以使用 Expression.Empty() 侥幸逃脱,但就像 juharr 所说,这有点毫无意义。

标签: c# resharper c#-7.0


【解决方案1】:

如您所见,表达式主体使用 lambda 运算符(“=>”)。如果您仍想将空的 void 方法编写为表达式主体,可以使用 Expression.Empty() 来表明 Foo() 是一个空 (void) 表达式。

返回 void 或 Task 的方法也应该使用不返回任何内容的表达式来实现。 (https://docs.microsoft.com/en-us/archive/msdn-magazine/2014/october/csharp-the-new-and-improved-csharp-6-0)

下面的代码应该可以工作。

public void Foo() => Expression.Empty();

我也同意你最后的评论,这是一个 ReSharper 错误。

【讨论】:

  • Expression.Empty 没有任何意义,因为代码与表达式树无关。
  • @svick 您使用 Expression.Empty() 在 lambda 表达式中返回 void。表达式主体也是一个 lambda 表达式。
  • 您使用Expression.Empty() 返回void手动构建表达式树时。表达式体与表达式树无关。
  • 命名空间名称(System.Linq.Expressions)不够用?然后考虑the description of the namespace:“System.Linq.Expressions 命名空间包含使语言级代码表达式能够以表达式树形式表示为对象的类、接口和枚举。”这根本不能描述你在做什么。
  • 是的,它们与空正文不同,但这也适用于Expression.Empty()。如果你查看反编译的代码,你会看到public void Foo() { Expression.Empty(); }
【解决方案2】:

来自docs

表达式主体定义具有以下一般语法:

成员 => 表达式;

其中表达式是一个有效的表达式

还有:

表达式体方法由一个表达式组成 返回一个值,其类型与方法的返回类型相匹配,对于 返回 void 的方法,执行某些操作

因此,如果您想使用表达式主体成员,您实际上确实需要... 表达式(惊喜!)

但你仍然可以使用常规样式:

string Property
{
    get => _value;
    set { } // empty
}

void Method() { } // empty

【讨论】:

    【解决方案3】:

    new object() 更好。

    Expression.Empty() 真的没有任何意义。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-02-02
      • 2020-12-11
      • 2018-08-15
      • 2018-08-21
      • 1970-01-01
      • 2022-01-19
      • 1970-01-01
      相关资源
      最近更新 更多