考虑以下代码:
object objFoo = MakeFoo(); // object MakeFoo(){return new Foo();}
MethodInfo methodInfo = typeof(Program).GetMethod("Baz"); // Foo Baz(){return foo;}
Type typeFoo = methodInfo.ReturnType;
var result = (typeFoo)objFoo;
我是否需要对 typeFoo
施展魔法才能得到结果?
最佳答案
没有:-)
案例 1:
object objFoo = MakeFoo(); // object MakeFoo(){return new Foo();}
Foo result = (Foo)objFoo;
这里没有反射,因为你在编译时知道Foo
类型。
案例 2: 接口(interface)。通常是最好的...您不知道 MakeFoo
返回什么,但您知道它是一个 IFoo
接口(interface)...
object objFoo = MakeFoo(); // object MakeFoo(){return new Foo();}
IFoo result = (IFoo)objFoo;
情况 3:您不确定 MakeFoo
是否返回 Foo
object objFoo = MakeFoo(); // object MakeFoo(){return new Foo();}
if (objFoo is Foo)
{
Foo result = (Foo)objFoo;
}
或者,类似的
object objFoo = MakeFoo(); // object MakeFoo(){return new Foo();}
Foo foo = objFoo as Foo;
if (foo != null)
{
// use foo
}
情况 4:类型 Foo
对您的程序来说是完全未知的。您没有可引用的 Foo
类...
object objFoo = MakeFoo(); // object MakeFoo(){return new Foo();}
Type typeFoo = objFoo.GetType(); // You should check for null values before!
// and now?
dynamic foo = objFoo;
// because you know that foo can Quack(1, 2, 3)!
string result = foo.Quack(1, 2, 3);
// note that it will explode with a RuntimeBinderException if there is no
// string Quack(int, int, int) method!
dynamic
内部使用了反射。您可以直接使用反射来获取 Quack
方法并调用它
案例5:与案例4相同,但直接使用反射:
object objFoo = MakeFoo(); // object MakeFoo(){return new Foo();}
Type typeFoo = objFoo.GetType(); // You should check for null values before!
MethodInfo mi = type.GetMethod("Quack"); // You should check if the Quack method
// exists
string result = (string)mi.Invoke(objFoo, new object[] { 1, 2, 3 });
或者,通过一些合理性检查,如果您不确定 foo
是否可以正确Quack
:
MethodInfo mi = type.GetMethod("Quack",
BindingFlags.Instance | BindingFlags.Public,
null,
new[] { typeof(int), typeof(int), typeof(int) },
null);
if (mi != null && typeof(string).IsAssignableFrom(mi.ReturnType))
{
string result = (string)mi.Invoke(objFoo, new object[] { 1, 2, 3 });
}
Case -Infinity: Foo
类型对于您的程序来说是完全未知的。您没有可引用的 Foo
类。您没有 IFoo
接口(interface)。你甚至不知道 Foo
是什么,你只知道它是一个类(或者它可能是一个装箱的 struct
,但它并没有改变你的观点 View ...它不能是一个interface
因为最后必须总是有一个具体的class
/struct
在每个 后面界面
)。您不知道它的方法、字段和属性(因为您不知道 Foo
是什么)。
即使您可以将对象
转换为这个未知类,您又能做什么呢?你不能在你的代码中有接受它作为参数/返回值的方法,因为如果你有:
int INeedFoo(Foo par) { return 0; }
那么您显然会知道 Foo
。 .NET 库不能有接受它作为参数/返回值的方法,因为如果有,您就会知道 Foo
。
你唯一能做的就是将它传递给你通过反射发现的其他方法,这些方法接受 Foo
作为参数......但是 Invoke
方法接受一个object
数组作为参数...您无需强制转换 object
即可调用 Invoke
!你只需要将它放在数组中。
关于c# - 转换为 C# 中的反射类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18052562/