我有一个Thing
类可以从string
隐式转换。当我直接调用带有Thing
参数的方法时,string
到Thing
的投射正确完成。
但是,如果我使用反射来调用相同的方法,则会抛出异常
System.ArgumentException : Object of type 'System.String' cannot be
converted to type 'Things.Program+Thing'.
也许这是有充分理由的,但我无法弄明白。有人知道如何使用反射来实现这个工作吗?
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:请不要讨论为什么隐式转换或反射不好。
答案 0 :(得分:10)
诀窍是要意识到编译器会为隐式转换运算符创建一个名为op_Implicit
的特殊静态方法。
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 });
答案 1 :(得分:4)
找到一个使用TypeConverter的答案(如赛义德提到的)
似乎可以完成这项工作。
答案 2 :(得分:1)
在这种特定情况下,您可以通过数组类型进行转换,即
showThingReflected.Invoke(this, new Thing[] {"foo"});
但那是一种“作弊”。通常,您不能指望Invoke
考虑用户定义的implicit operator
。必须在编译时推断此转换。