我正在尝试编写调用 Parallel.ForEach 的动态方法。我检查了示例类的 IL,注意到生成了一个名为 <>c__DisplayClass# 的嵌套类型。
我确实设法创建了 Parallel.ForEach 的动态实现,但我的嵌套类是普通类型。它没有被命名为 <>c__....
而且我认为因为在 Reflector 中检查它时我生成的代码看起来有点不同:
private void SayHello(string name)
{
SayHelloInvoker invoker = new SayHelloInvoker(name);
Parallel.ForEach<ITest>(this, new Action<ITest>(invoker.SayHello));
}
但是在 Reflector 中检查的编译代码看起来像:
private void SayHello(string name)
{
Parallel.ForEach<ITest>(this, delegate (ITest x) { x.SayHello(name)); });
}
当前的实现工作正常,但我仍然想弄清楚生成嵌套类型为 <>c__.... 的问题在哪里。
所以,如果有人能指出我正确的方式,这样我就可以满足我的好奇心。 :)
I'm trying to write dynamic method that calls Parallel.ForEach. I have checked a IL of a sample class and I noticed that there's a nested type generated that's named <>c__DisplayClass#
I did manage to create a dynamic implementation of Parallel.ForEach but my nested class is of normal type. It is not named as <>c__....
And I think because of that my generated code looks a bit different when inspecting it in Reflector:
private void SayHello(string name)
{
SayHelloInvoker invoker = new SayHelloInvoker(name);
Parallel.ForEach<ITest>(this, new Action<ITest>(invoker.SayHello));
}
But the compile code inspected in Reflector looks like:
private void SayHello(string name)
{
Parallel.ForEach<ITest>(this, delegate (ITest x) { x.SayHello(name)); });
}
Current implementation works just fine but I would still like to figure out where's the catch in generating nested typed as <>c__....
So please if someone can point me in the right way so I can satisfy my curiosity. :)
发布评论
评论(1)
当您创建使用父方法中的变量的匿名方法时,C# 编译器会生成一个名为
<>c_...
的闭包类来共享这些变量。有关更多信息,请参阅我的博客文章< /a>.
如果动态生成一个方法,您可以做任何您想做的事情来确保该方法可以访问它需要的变量。
在您的情况下,您的
SayHelloInvoker
(大概)与生成的闭包类型具有相同的作用,但具有更具可读性的名称,就像我的 GreaterThan 类一样href="http://blog.slaks.net/2011/06/delegates-vs-function-pointers-part-3-c.html" rel="nofollow">之前的无闭包示例。When you make an anonymous method that uses variables from the parent method, the C# compiler generates a closure class named
<>c_...
to share those variables.For more information, see my blog post.
If you generate a method dynamically, you can do whatever you want to ensure that the method has access to the variables it needs.
In your case, your
SayHelloInvoker
is (presumably) serving the same role as the generated closure type, but with a more readable name, just like theGreaterThan
class from my previous closure-less example.