example - remarks c#
Cómo lanzar implícitamente en un método reflejado (3)
El truco es darse cuenta de que el compilador crea un método estático especial llamado op_Implicit
para su operador de conversión implícito.
object arg = "foo";
// Program.showThing(Thing t)
var showThingReflected = GetType().GetMethod("showThing");
// typeof(Thing)
var paramType = showThingReflected.GetParameters()
.Single()
.ParameterType;
// Thing.implicit operator Thing(string s)
var converter = paramType.GetMethod("op_Implicit", new[] { arg.GetType() });
if (converter != null)
arg = converter.Invoke(null, new[] { arg }); // Converter exists: arg = (Thing)"foo";
// showThing(arg)
showThingReflected.Invoke(this, new[] { arg });
Tengo una Thing
clase que se puede convertir implícitamente desde una string
. Cuando llamo a un método con un parámetro Thing
directamente, la conversión de string
a Thing
se realiza correctamente.
Sin embargo, si uso la reflexión para llamar al mismo método, se produce la excepción.
System.ArgumentException : Object of type ''System.String'' cannot be
converted to type ''Things.Program+Thing''.
Tal vez haya una buena razón para esto, pero no puedo entenderlo. ¿Alguien tiene una idea de cómo hacer que esto funcione utilizando la reflexión?
namespace Things
{
class Program
{
public class Thing
{
public string Some;
public static implicit operator Thing(string s)
{
return new Thing {Some = s};
}
}
public void showThing(Thing t)
{
Console.WriteLine("Some = " + t.Some);
}
public void Main()
{
showThing("foo");
MethodInfo showThingReflected = GetType().GetMethod("showThing");
showThingReflected.Invoke(this, new dynamic[] {"foo"});
}
}
}
Meta: Por favor, no hay discusiones sobre por qué la conversión implícita o la reflexión es mala
En este caso específico, puede realizar la conversión a través del tipo de matriz, es decir
showThingReflected.Invoke(this, new Thing[] {"foo"});
Pero eso es una especie de "trampa". En general, no puede esperar que Invoke
considere su implicit operator
definido por el usuario. Esta conversión debe ser inferida en tiempo de compilación.
Encontró una respuesta que utiliza un TypeConverter (como menciona Saeed)
Parece hacer el trabajo.
TypeConverter para conversión implícita cuando se utiliza reflexión