检查 IEnumerable<T> 是否由 yield 关键字创建的正确方法

Correct way to check if IEnumerable<T> is created by a yield keyword

检查 IEnumerable<T> 是否由 yield 关键字?

样本:

public IEnumerable<int> GetMeSomeInts() 
{
   // Unknown implementation
}

某处:

IEnumerable<int> someInts = GetMeSomeInts() ;

if (someInts is generatedbyayield) // <- What should be this condition ? 
      someInts = someInts.ToList() ; 

由 yield 关键字创建的状态机并非设计为 "detectable"。如果您找到检测它的方法,您将不得不依赖一些特定于实现的提示(例如类型名称的特定模式;一些示例在您的问题的评论中给出),这些不是 C# 的一部分规范,因此可能随时更改。

因此,没有正确 方法来检查IEnumerable<T> 是否由yield 关键字生成。我认为 正确的 方法是不检查。这就是接口的用途:它们隐藏实现。


既然你没有提到为什么你想查明IEnumerable是否是由yield关键字生成的,我会胡乱猜测并假设你其实想问的是:

How can I materialize an IEnumerable if it has not been materialized yet?

该问题已得到解答:

  • Is there a way to Memorize or Materialize an IEnumerable?

我不一定会说这是正确的方式,但是A方式是:

someInts.GetType().Name.Contains("<Yielded>")

这个名字很反常,估计还算靠谱吧。由于您依赖于深层内部结构,它可能会在任何 .NET 版本之间发生变化,尽管我觉得它可能不会't/hasn'。

如果您使用它,请确保进行单元测试以对其进行完整性检查。这样一来,如果内部结构发生变化,您的单元测试将在构建服务器上失败。