转换为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或动态,您将无法使用其任何方法。
- 无法将int类型转换为System.Windows.Forms.Label
- 如何在ObservableCollection上引发CollectionChanged事件,并将更改的项目传递给它?
- 线程阻止UI
- entity framework6和Moq4:是否有可能让模拟的DbSet在其范围的持续时间内保留添加的数据?
- 如何在C#中有效地处理许多更新对象?
- entity framework4.2“该类型不归因于EdmEntityTypeAttribute,但包含在使用EdmSchemaAttribute归属的程序集中
- 如何使用c#中的“format-list”和“out-file”管道调用powershell命令?
- 使用数组初始化语法在C#上初始化Dictionary实例时会发生什么?
- 加密BouncyCastle RSA密钥对并存储在SQL2008数据库中