I have a class Thing
that is implicitly castable from a string
. When I call a method with a Thing
parameter directly the cast from string
to Thing
is done correctly.
However if I use reflection to call the same method it throws the exception
System.ArgumentException : Object of type 'System.String' cannot be
converted to type 'Things.Program+Thing'.
Maybe there is a good reason for this, but I can't figure it out. Does somebody have an idea how to get this working using reflection?
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: Please, no discussions why implicit casting or reflection is bad.
Found an answer which uses a TypeConverter (as Saeed mentions)
Seems to do the job.
The trick is to realize that the compiler creates a special static method called op_Implicit
for your implicit conversion operator.
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 });
In this specific case you can make the conversion through the array type, that is
showThingReflected.Invoke(this, new Thing[] {"foo"});
but that's a kind of "cheating". In general, you cannot expect the Invoke
to consider your user-defined implicit operator
. This conversion must be inferred compile-time.
来源:https://stackoverflow.com/questions/11544056/how-to-cast-implicitly-on-a-reflected-method-call