requerido que parametro ningun metodos metodo mandar llamar funciones formal firma definicion dado corresponda como clases argumento c# .net c#-4.0 dynamic compiler-construction

c# - parametro - ¿Por qué obtengo este error de compilación al intentar llamar a un constructor/método base que toma un argumento dinámico?



no se ha dado ningun argumento que corresponda al parametro formal requerido c# (1)

Mientras refactorizaba un código, me encontré con este extraño error de compilación:

La llamada al constructor necesita ser despachada dinámicamente, pero no puede ser porque es parte de un inicializador de constructor. Considera lanzar los argumentos dinámicos.

Parece ocurrir cuando se intenta llamar a los métodos / constructores base que toman argumentos dinámicos. Por ejemplo:

class ClassA { public ClassA(dynamic test) { Console.WriteLine("ClassA"); } } class ClassB : ClassA { public ClassB(dynamic test) : base(test) { Console.WriteLine("ClassB"); } }

Funciona si lanzo el argumento a object , así:

public ClassB(dynamic test) : base((object)test)

Entonces, estoy un poco confundido. ¿Por qué tengo que poner este desagradable yeso? ¿Por qué el compilador no puede entender lo que quiero decir?


La cadena de constructores debe determinarse con certeza en tiempo de compilación: el compilador debe elegir una sobrecarga para poder crear una IL válida. Mientras que la resolución de sobrecarga normal (por ejemplo, para llamadas a métodos) puede diferirse hasta el momento de la ejecución, eso no funciona para las llamadas al constructor encadenadas.

EDITAR: en el código "normal" de C # (antes de C # 4, básicamente), toda la resolución de sobrecarga se realiza en tiempo de compilación. Sin embargo, cuando una invocación de miembro implica un valor dinámico, eso se resuelve en el momento de la ejecución. Por ejemplo considere esto:

using System; class Program { static void Foo(int x) { Console.WriteLine("int!"); } static void Foo(string x) { Console.WriteLine("string!"); } static void Main(string[] args) { dynamic d = 10; Foo(d); } }

El compilador no emite una llamada directa a Foo aquí; no puede, porque en la llamada Foo(d) no sabe a qué sobrecarga se resolvería. En su lugar, emite código que hace una especie de minirpilación "justo a tiempo" para resolver la sobrecarga con el tipo real del valor de d en el momento de la ejecución.

Ahora eso no funciona para el encadenamiento de constructores, ya que un IL válido debe contener una llamada a un constructor de clase base específico. (No sé si la versión dinámica ni siquiera se puede expresar en IL, o si puede, pero el resultado no sería verificable).

Se podría argumentar que el compilador de C # debería ser capaz de decir que solo hay un constructor visible al que se puede llamar, y ese constructor siempre estará disponible ... pero una vez que comienzas por ese camino, terminas con un lenguaje que es muy complicado de especificar Los diseñadores de C # generalmente toman la posición de tener reglas más simples que de vez en cuando no son tan poderosas como te gustaría que fueran.