【问题标题】:IEnumerable Expression-Bodied Member C#IEnumerable 表达式体成员 C#
【发布时间】:2023-03-12 12:19:01
【问题描述】:

我在 C# 中有一个 get-only 属性,它返回 IEnumerable。如果该属性只会产生一次,那么我可以像这样定义我的属性:

public IEnumerable Derp {
    get { yield return new SomeObject(); }
}

但是我将如何使用 C#6 表达式主体成员来执行此操作?以下方法有效:

// These definitions do NOT work
public IEnumerable Derp => yield return new SomeObject();
public IEnumerable Derp => yield new SomeObject();

返回编译器错误 CS0103:“名称 'yield' 在当前上下文中不存在”。 yielding 表达式体成员在 C#6 中是否可能?在 C#7 中怎么样?

我知道只返回一次的 IEnumerable 成员看起来很臭,但我主要只是好奇。我在尝试使用 NUnit TestCaseSource API 时遇到了这种情况,试图提供一种只产生一个测试用例的方法。我还可以看到这与想要定义要使用 StartCoroutine() 调用的表达式主体方法的 Unity 开发人员有关。

无论如何,提前感谢您的想法!

【问题讨论】:

  • 你为什么不能Derp => new[] { new SomeObject() };?你真的不需要在这里使用yield

标签: c# ienumerable c#-6.0 yield-return c#-7.0


【解决方案1】:

表达式主体的函数/属性不能有语句...你不能,例如:

static int Test(int x) => if (x > 0) x else 0;

甚至

static int Test(int x) => return x;

yield 是一个声明...你不能使用它:-)

请注意,您可以:

IEnumerable<SomeObject> Derp => new[] { new SomeObject() };

来自Roslyn github pageNew Language Features in C# 6

2.1 类方法成员上的表达式主体 可以使用“lambda 箭头”为方法以及用户定义的运算符和转换赋予一个表达式主体:

效果与方法具有带有单个 return 语句的块体完全相同。

对于返回 void 的方法——以及返回异步方法的 Task——箭头语法仍然适用,但是 箭头后面的表达式必须是语句表达式(就像 lambdas 的规则一样):

所以void返回方法有一个例外,但它仍然只涵盖调用方法(你可以=&gt; Console.WriteLine("Hello");但你不能=&gt; if ())。

【讨论】:

  • 有趣。我知道您不能在表达式主体成员中使用语句,但我不知道 yield 算作语句!哇,+1 提醒我 void 方法可以是表达式,我完全认为这在 C#7 之前是不可能的!
  • 顺便说一句,我很确定最新的 Roslyn 开源存储库现在是 GitHub 上的 here。 :)
  • @Rabadash8820 在C# 7.0 中,他们添加了=&gt; throw new Exception() 的选项(但这更多的是throw 关键字的工作变化,而不是在@ 之后使用它是合法的987654334@ 和 ? : 运算符
  • 如果您的方法或属性只有一个语句并且该语句可以写为表达式,那么您可以使用表达式体函数成员。 int Test(int x) => if (x > 0) x else 0; // 无效的 int Test(int x) => x > 0 ? x:0; // 好的
猜你喜欢
  • 1970-01-01
  • 2021-01-03
  • 1970-01-01
  • 2017-11-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多