remarks example cref c# .net reflection casting implicit-cast

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.