转换为C#中的reflection类型

请考虑以下代码:

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:接口。 通常是最好的…你不知道MakeFoo究竟返回了什么,但你知道它是一个IFoo接口……

 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内部使用reflection。 您可以直接使用reflection来获取Quack方法并调用它

案例5:如案例4,但使用直接reflection:

 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接口。 你甚至不知道Foo是什么,你只知道它是一个类(或者它可能是一个盒装struct ,但它不会从你的角度改变……它不能是一个interface因为在每个interface后面必须始终有一个具体的class / struct 。 你不知道它的方法,它的字段,它的属性(因为你不知道Foo是什么)。

即使你可以将一个object投射到这个未知的类,你还能做什么? 您不能在代码中使用接受它作为参数/返回值的方法,因为如果您拥有以下某个地方:

 int INeedFoo(Foo par) { return 0; } 

那么显然你会知道Foo 。 .NET库不能有接受它作为参数/返回值的方法,因为如果有,你会知道Foo

你唯一能做的就是将它传递给你通过reflection发现的其他方法,这些方法接受Foo作为参数…但是Invoke方法接受一个object数组作为参数……你不需要转换你的object打电话给Invoke ! 你只需要把它放在数组中。

这相当于:

 object objFoo = MakeFoo(); Foo result = (Foo)objFoo; 

将对象转换为编译时未知的类型没有任何意义 – 您将无法使用它:

 object objFoo = MakeFoo(); UnkownType result = (UknownType)objFoo; 

由于您不知道UknownType是什么,因此如果不采用reflection或动态,您将无法使用其任何方法。