您可以通过扩展方法使 class 可枚举吗?特别是 System.Range

Can you make a class enumerable via extension methods? In particular, System.Range

我现在正在使用最新的 C# 8,我正在研究新的 System.Range,想看看是否有类似

的东西
foreach (int i in 5..8)
{ 
}

是可能的,但在撰写本文时(使用绝对前沿预览)给我一个错误。

然后我想知道我是否可以通过在静态 class 中执行类似以下的操作来使其可枚举,因为也许 foreach 循环实际上并不关心,只是想要一些存在方法可用,所以我尝试了:

public static IEnumerator GetEnumerator(this Range range) 
{
    // ...
}

但是编译器对此并不满意。

这可能吗?或者我只是在实施可枚举错误? IDE 中的错误消息告诉我 GetEnumerator() 需要可用于 foreach 到 运行,但是因为我无权访问 class 并且不能简单地执行 : IEnumerable<int> 然后从中生成方法并执行所需的操作,我不知道这是否意味着我被卡住了或者我是否编码不正确。

我的错误:

    foreach (int i in 1..5)
    {
        Console.WriteLine(i);
    }

[CS1579] foreach statement cannot operate on variables of type 'Range' because 'Range' does not contain a public instance definition for 'GetEnumerator'

$ dotnet --version

3.0.100-preview8-013656

项目目标 netcoreapp3.0,C# 语言水平为 preview

不,foreach 循环不适用于扩展方法,不像(比如)await。它 基于模式的,因为它不需要实施 IEnumerable<T>IEnumerable - 如果您有合适的 GetEnumerator() instance 方法返回适当的类型(具有 MoveNext()Current 成员),这很好。但是编译器不会像您那样寻找 GetEnumerator() 扩展方法。已经 proposed, but I don't know of any plan to do this, and I'd be very surprised if it were in C# 8 (given the list of features).

您需要像这样编写一个扩展方法:

 public static IEnumerable<int> AsEnumerable(this Range range)
 {
     ...
 }

然后你可以使用

 foreach (int x in (1..5).AsEnumerable())

...但是如果任一索引是 "from the end" 而不是 "from the start",您仍然需要弄清楚该怎么做,而且我不确定将其作为仅执行时检查,真的。

基本上,范围主要设计用于在另一个上下文内切片而不是独立的。