在生成的迭代器块中获取对“ this”的引用的任何方法?
作者:互联网
从C#2.0开始,我们已经能够在类内部声明迭代器块,并使用yield return关键字从中返回值.在后台,编译器已将我们相当简单的迭代器块慷慨地转换为自己的类,即状态机,该机完全实现IEnumerable或IEnumerator接口.使用ILSpy或Reflector,您可以了解这些类的外观.
在C#3.5中,将扩展方法添加到该语言中,提供了一种简单的方法来编写静态方法,这些方法将出现在现有类或接口的智能感知弹出窗口中.
我感兴趣的是将这两个概念结合起来,因此我遇到了困难.我的挫败感围绕着一个事实,即在迭代器块中,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";
}
}
不幸的是,在这种情况下,它引用了IteratorExample的一个实例,而不是所生成的MyIterator类的一个实例.有什么方法可以在迭代器中获得引用,还是我必须重新考虑自己的计划?
解决方法:
没有干净的方法,没有.所有这些用法都会被拦截,并引用声明实例.
您可能会做一些令人讨厌的事情,包括滥用堆栈或类似方法,但是没有什么整洁的事.您也许可以将迭代器链接为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()
标签:iterator,extension-methods,c 来源: https://codeday.me/bug/20191208/2089517.html