use*_*923 16 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;
Run Code Online (Sandbox Code Playgroud)
我需要做一些魔法typeFoo来获得结果吗?
xan*_*tos 53
不:-)
情况1:
object objFoo = MakeFoo(); // object MakeFoo(){return new Foo();}
Foo result = (Foo)objFoo;
Run Code Online (Sandbox Code Playgroud)
这里没有反映,因为你知道Foo编译时的类型.
案例2:接口.通常是最好的...你不知道到底是什么MakeFoo回报,但你知道这是一个IFoo界面......
object objFoo = MakeFoo(); // object MakeFoo(){return new Foo();}
IFoo result = (IFoo)objFoo;
Run Code Online (Sandbox Code Playgroud)
案例3:你不确定MakeFoo退货Foo
object objFoo = MakeFoo(); // object MakeFoo(){return new Foo();}
if (objFoo is Foo)
{
Foo result = (Foo)objFoo;
}
Run Code Online (Sandbox Code Playgroud)
或者,类似的
object objFoo = MakeFoo(); // object MakeFoo(){return new Foo();}
Foo foo = objFoo as Foo;
if (foo != null)
{
// use foo
}
Run Code Online (Sandbox Code Playgroud)
案例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!
Run Code Online (Sandbox Code Playgroud)
的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 });
Run Code Online (Sandbox Code Playgroud)
或者,通过一些健全性检查,如果您不确定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 });
}
Run Code Online (Sandbox Code Playgroud)
Case -Infinity: 类型Foo完全不为您的程序所知.您没有可Foo引用的类.你没有IFoo界面.你甚至不知道它Foo是什么,你只知道它是一个类(或者它是一个盒子struct,但它不会从你的角度改变......它不可能是interface因为最终必须永远是每个人的具体class/ struct背后interface.你不知道它的方法,它的字段,它的属性(因为你不知道是什么Foo).
即使你可以投入object这个未知的课程,你还能做什么?您不能在代码中使用接受它作为参数/返回值的方法,因为如果您拥有以下某个地方:
int INeedFoo(Foo par) { return 0; }
Run Code Online (Sandbox Code Playgroud)
那么显然你会知道的Foo..NET库不能有接受它作为参数/返回值的方法,因为如果有,你就会知道Foo.
你能做的唯一的事情就是把它传递给你通过反射接受发现一些其他的方法Foo作为参数......但Invoke方法接受一个数组object作为参数......你不需要投你的object来电Invoke!你只需要把它放在数组中.
这是谷歌关于投射到反射类型的第一个结果。
所以作为参考,如果某人想知道转换为反射类型的一般方法是什么:
public static class ObjectExtensions
{
public static T CastTo<T>(this object o) => (T)o;
public static dynamic CastToReflected(this object o, Type type)
{
var methodInfo = typeof(ObjectExtensions).GetMethod(nameof(CastTo), BindingFlags.Static | BindingFlags.Public);
var genericArguments = new[] { type };
var genericMethodInfo = methodInfo?.MakeGenericMethod(genericArguments);
return genericMethodInfo?.Invoke(null, new[] { o });
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
36912 次 |
| 最近记录: |