Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

163
Visualizações
Cambios en el comportamiento del almacenamiento en caché del delegado en Roslyn

Dado el siguiente código:

 public class C { public void M() { var x = 5; Action<int> action = y => Console.WriteLine(y); } }

Usando VS2013, .NET 4.5. Al mirar el código descompilado, podemos ver que el compilador está almacenando en caché al delegado en el sitio de la llamada:

 public class C { [CompilerGenerated] private static Action<int> CS$<>9__CachedAnonymousMethodDelegate1; public void M() { if (C.CS$<>9__CachedAnonymousMethodDelegate1 == null) { C.CS$<>9__CachedAnonymousMethodDelegate1 = new Action<int>(C.<M>b__0); } Action<int> arg_1D_0 = C.CS$<>9__CachedAnonymousMethodDelegate1; } [CompilerGenerated] private static void <M>b__0(int y) { Console.WriteLine(y); } }

Mirando el mismo código descompilado en Roslyn (usando TryRoslyn ), produce el siguiente resultado:

 public class C { [CompilerGenerated] private sealed class <>c__DisplayClass0 { public static readonly C.<>c__DisplayClass0 CS$<>9__inst; public static Action<int> CS$<>9__CachedAnonymousMethodDelegate2; static <>c__DisplayClass0() { // Note: this type is marked as 'beforefieldinit'. C.<>c__DisplayClass0.CS$<>9__inst = new C.<>c__DisplayClass0(); } internal void <M>b__1(int y) { Console.WriteLine(y); } } public void M() { Action<int> arg_22_0; if (arg_22_0 = C.<>c__DisplayClass0.CS$<>9__CachedAnonymousMethodDelegate2 == null) { C.<>c__DisplayClass0.CS$<>9__CachedAnonymousMethodDelegate2 = new Action<int>(C.<>c__DisplayClass0.CS$<>9__inst.<M>b__1); } } }

Ahora podemos ver que el delegado ahora se eleva a una clase privada dentro de C , un comportamiento similar al que estamos acostumbrados a ver al cerrar sobre una variable de instancia/campo (cierre).

Sé que este es un detalle de implementación que puede estar sujeto a cambios en cualquier momento.

Todavía me pregunto, ¿cuáles son los beneficios de llevar al delegado a una nueva clase y almacenarlo en caché allí en lugar de simplemente almacenarlo en caché en el sitio de la llamada?

Editar:

Este problema habla sobre el mismo comportamiento que se preguntó aquí.

over 4 years ago · Santiago Trujillo
2 Respostas
Responde à pergunta

0

Sí. La parte más importante es que el método que contiene la implementación de lambda ahora es un método de instancia.

Puede ver a un delegado como un intermediario que recibe una llamada de instancia a través de Invoke y envía esa llamada de acuerdo con la convención de llamadas del método de implementación.

Tenga en cuenta que existen requisitos ABI de la plataforma que especifican cómo se pasan los argumentos, cómo se devuelven los resultados, qué argumentos se pasan a través de registros y en cuáles, cómo se pasa "esto", etc. La violación de estas reglas puede tener un impacto negativo en las herramientas que se basan en el recorrido de la pila, como los depuradores.

Ahora, si el método de implementación es un método de instancia, lo único que debe suceder dentro del delegado es parchear "esto", que es la instancia delegada en el momento de Invocar, para que sea el objeto de destino adjunto. En ese momento, dado que todo lo demás ya está donde debe estar, el delegado puede saltar directamente al cuerpo del método de implementación. En muchos casos, esto es notablemente menos trabajo de lo que debería suceder si el método de implementación fuera un método estático.

over 4 years ago · Santiago Trujillo Relatório

0

Todavía me pregunto, ¿cuáles son los beneficios de llevar al delegado a una nueva clase y almacenarlo en caché allí en lugar de simplemente almacenarlo en caché en el sitio de la llamada?

Te has perdido otro detalle realmente importante: ahora es un método de instancia. Creo que esa es la clave aquí. IIRC, se descubrió que invocar a un delegado que estaba "respaldado" por un método de instancia era más rápido que invocar a un delegado respaldado por un método estático, que es la motivación detrás del cambio.

Todo esto son rumores, vagamente recordados de pasar tiempo con Dustin Campbell y Kevin Pilch-Bisson (ambos del equipo de Roslyn) en CodeMash, pero tendría sentido dado el código que ha mostrado.

(No he validado la diferencia de rendimiento por mí mismo, y parece que está al revés... pero las partes internas de CLR pueden ser así de divertidas...)

over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda