从C#2.0开始,我们已经能够在类中声明迭代器块并使用yield return
关键字从它们返回值。在幕后,编译器慷慨地将我们相当简单的迭代器块转换为它自己的类,一个完全实现IEnumerable
或IEnumerator
接口的状态机。使用ILSpy或Reflector,您可以了解这些类的外观。
在C#3.5中,扩展方法被添加到语言中,提供了一种编写静态方法的简单方法,这些方法将出现在现有类或接口的intellisense弹出窗口中。
我感兴趣的是将这两个概念结合起来,这样做我遇到了困难。我的挫败感在于,在迭代器块中,this
关键字指的是迭代器块所在的类,而不是包含迭代器块实现的编译器生成的类。
我想做的是这样的事情:
public static class IteratorExtensions
{
public static void DoSomething<T>(this IEnumerable<T> iterator)
{
Console.WriteLine("Running iterator block of type :" + typeof(T).Name);
}
}
public class IteratorExample
{
public IEnumerable<string> MyIterator()
{
yield return "Hello";
this.DoSomething();
yield return "World";
}
}
不幸的是,在此上下文中,this
引用了IteratorExample的实例,而不是生成的MyIterator类的实例。有没有办法在迭代器中获取引用,还是我必须重新考虑我的计划?
答案 0 :(得分:3)
没有干净的方式,没有。所有this
用法都被截获,并引用声明实例。
你可以可能做一些涉及滥用堆栈或类似事件的可怕事情,但没有什么是整洁的。您可以链接迭代器LINQ风格吗?即。
public static IEnumerable<T> WithLogging<T>(this IEnumerable<T> source)
{
source.DoSomething();
try {
foreach(var item in source) yield return item;
} finally {
source.DoSomethingElse();
}
}
并使用originalIterator.WithLogging()
答案 1 :(得分:0)
我认为你不能做你想做的事情 - 我认为语言规范隐藏了实现类,所以它不会限制可能使用不同机制的同一特性的未来实现。 / p>
答案 2 :(得分:0)
这不起作用,所以你必须重新考虑你的计划。
如果您提供有关您希望实现的目标的更多信息,我们可能会帮助您找到替代解决方案。