Basado en following question, encontré un comportamiento extraño del compilador C#.rareza del compilador C# con delegados constructores
El siguiente es válida # C:
static void K() {}
static void Main()
{
var k = new Action(new Action(new Action(K))));
}
Lo que parece extraño es el compilador 'deconstruir' el delegado pasado.
salida El ILSpy es como sigue:
new Action(new Action(new Action(null, ldftn(K)), ldftn(Invoke)).Invoke);
Como uno puede ver, decide automáticamente para utilizar el método de la delegado Invoke
. ¿Pero por qué?
Tal como está, el código no está claro. ¿Tenemos un delegado triplemente envuelto (real) o el delegado interno simplemente 'copiado' a los externos (mi pensamiento inicial).
Sin duda, si la intención era como el compilador emite el código, se debería haber escrito:
var k = new Action(new Action(new Action(K).Invoke).Invoke);
similar al código descompilación.
¿Alguien puede justificar el motivo de esta transformación "sorprendente"?
Actualización:
sólo puedo pensar en un posible caso de uso para esto; delegar la conversión de tipo. Por ejemplo:
delegate void Baz();
delegate void Bar();
...
var k = new Baz(new Bar(new Action (K)));
Tal vez el compilador debe emitir una advertencia si se utilizan los mismos tipos de delegado.
No está claro qué quiere decir con "es el delegado interior sólo 'copiado 'a los exteriores' - ¿qué es exactamente lo que esperabas? ¿Una única instancia de delegado? –
Fuera de interés, ¿dónde emplearías tal construcción? Parece que el "delegado triplemente envuelto" se comerá al programador poco astuto para el desayuno ... – MoonKnight
@JonSkeet: esperaba que fuera más parecido a 'nueva Acción (a.Target, a.Método)' en lugar de 'nueva Acción (a.Invocar)'. IOW, sin envoltura. – leppie