投射到C#中的反射类型 [英] Cast to a reflected Type in C#

查看:130
本文介绍了投射到C#中的反射类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请考虑以下代码:

  object objFoo = MakeFoo // Object MakeFoo(){return new Foo();} 
MethodInfo methodInfo = typeof(Program).GetMethod(Baz); // Foo Baz(){return foo;}
类型typeFoo = methodInfo.ReturnType;
var result =(typeFoo)objFoo;

我需要做一些魔法与 typeFoo

否: - )



情况1:

  object objFoo = MakeFoo // object MakeFoo(){return new Foo();} 
Foo result =(Foo)objFoo;

这里没有反映,因为你知道 Foo type in compile time。



情况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)
{
//使用foo
}

案例4:键入 Foo 对于您的程序是完全未知的。您没有 Foo 类可引用...

 对象objFoo = MakeFoo(); // object MakeFoo(){return new Foo();} 
类型typeFoo = objFoo.GetType(); //你应该先检查空值!

//现在?

dynamic foo = objFoo;

//因为你知道foo可以Quack(1,2,3)!
string result = foo.Quack(1,2,3);

//注意,如果没有
//字符串Quack(int,int,int)方法,它会爆炸RuntimeBinderException!

动态您可以直接使用反射来获得 Quack 方法并调用



情况5:如情况4,但使用直接反射:

  object objFoo = MakeFoo // object MakeFoo(){return new Foo();} 
类型typeFoo = objFoo.GetType(); //你应该先检查空值!
MethodInfo mi = type.GetMethod(Quack); //你应该检查Quack方法
//是否存在
string result =(string)mi.Invoke(objFoo,new object [] {1,2,3});

或者,如果你不确定 foo 可以正确地:

  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: c> Foo 对于你的程序是完全未知的。您没有可引用的 Foo 类别。您没有 IFoo 界面。你甚至不知道 Foo 是什么,你只知道它是一个类(或者是一个盒子 struct ,但它不会改变从你的观点...它不能是一个接口,因为最终总是有一个具体的<$ c $每个接口后面的 class / struct 你不知道它的方法,它的字段,它的属性(因为你不知道 Foo 是什么)。



即使你可以向这个未知类施放对象,你能做什么?你的代码中不能有方法接受它作为参数/返回值,因为如果你有:

  int INeedFoo(Foo par){return 0; } 

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



你唯一可以做的是将它传递给你通过反射发现接受 Foo 一个参数...但是 Invoke 方法接受一个 object 作为参数的数组...你不需要投入对象调用调用!你只需要把它放在数组中。


Consider the following code:

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;

Do I need to do some magic with typeFoo to get the result?

解决方案

No :-)

Case 1:

object objFoo = MakeFoo(); // object MakeFoo(){return new Foo();}
Foo result = (Foo)objFoo;

There is no reflection here, because you know the Foo type at compile time.

Case 2: interfaces. Normally the best one... You don't know what exactly MakeFoo returns, but you know it's an IFoo interface...

object objFoo = MakeFoo(); // object MakeFoo(){return new Foo();}
IFoo result = (IFoo)objFoo;

Case 3: you aren't sure MakeFoo returns Foo

object objFoo = MakeFoo(); // object MakeFoo(){return new Foo();}

if (objFoo is Foo)
{
    Foo result = (Foo)objFoo;
}

or, similar

object objFoo = MakeFoo(); // object MakeFoo(){return new Foo();}

Foo foo = objFoo as Foo;

if (foo != null)
{
    // use foo
}

Case 4: type Foo is completely unknown to your program. You don't have a Foo class referenceable...

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!

the dynamic internally uses reflection. You could use reflection directly to get the Quack method and call it

Case 5: as case 4, but using directly 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 });

or, with some sanity checks, if you aren't sure foo can Quack correctly:

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: type Foo is completely unknown to your program. You don't have a Foo class referenceable. You don't have an IFoo interface. You don't even know what a Foo is, you know only that it's a class (or perhaps it's a boxed struct, but it doesn't change from your point of view... It can't be an interface because in the end there must always be a concrete class/struct behind every interface). You don't know of its methods, its fields, its properties (because you don't know what Foo is).

Even if you can cast an object to this unknown class, what can you do? You can't have methods in your code that accept it as a parameter/return value, because if somewhere you had:

int INeedFoo(Foo par) { return 0; }

then clearly you would know of Foo. The .NET library can't have methods that accept it as a parameter/return value, because if it had, you would know of Foo.

The only thing you can do is pass it to some other methods that you discover through reflection that accept Foo as a parameter... But the Invoke method accepts an array of object as parameters... You don't need to cast your object to call Invoke! You only need to put it in the array.

这篇关于投射到C#中的反射类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆