c# - 转换为 C# 中的反射类型

标签 c# reflection types casting

考虑以下代码:

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/

相关文章:

c# - linq where 子句和计数导致空异常

ruby - 如何在 Ruby 中查找类的每个实例

java - 如何比较 Type 的实例是否相等

c - 我们什么时候应该使用 stdint.h 中定义的整数类型?

Python `type(x)==` 什么?

c# - 如何在c#中序列化DBParameters

c# - 更好地掌握接口(interface)

c# - WinForms C# .Net 4.0 中的功能区

c# - 使用反射从字符串中获取属性值

java - Java中原始数据类型的MIN_VALUE和MAX_VALUE