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.
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 });
Found an answer which uses a TypeConverter (as Saeed mentions)
Seems to do the job.
TypeConverter For Implicit Conversion when using reflection
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With