Reflection.Emit и Parallel.ForEach - PullRequest
       15

Reflection.Emit и Parallel.ForEach

2 голосов
/ 23 ноября 2011

Я пытаюсь написать динамический метод, который вызывает 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 __....

Поэтому, пожалуйста, если кто-то может указать мне правильный путь, чтобы я мог удовлетворить свое любопытство. :)

1 Ответ

1 голос
/ 23 ноября 2011

Когда вы создаете анонимный метод, который использует переменные из родительского метода, компилятор C # генерирует класс замыкания с именем <>c_... для совместного использования этих переменных.

Для получения дополнительной информации см. Мой блог .

Если вы генерируете метод динамически, вы можете делать все, что хотите, чтобы метод имел доступ к нужным ему переменным.
В вашем случае SayHelloInvoker (предположительно) выполняет ту же роль, что и сгенерированный тип замыкания, но с более читаемым именем, точно так же, как класс GreaterThan из моего предыдущего примера без замыкания .

...