我有一种奇怪的行为。
我使用以下方法将任何对象强制转换为任何给定的类型。
using System.Dynamic;
...
/// <summary>
/// Casts any object to passed type.
/// </summary>
/// <typeparam name="T">Wished type</typeparam>
/// <param name="obj">The object you want to be casted.</param>
public static T ToType<T>(this object obj) => (T)obj;
例如(对象为动态):
AnyLabel.Tag = new ExpandoObject();
AnyLabel.Tag.ToType<dynamic>().Item2 = new Form(); // works
现在跟随情况(动态到类型化对象):
// var is NOT from type form, why?:
var form = ToType<Form>(AnyLabel.Tag.ToType<dynamic>().Item2);
// the other way works like desired:
var form2 = ((Form)AnyLabel.Tag.ToType<dynamic>().Item2);
我无法使用转换扩展程序àla:
访问任何表单属性/方法ToType<Form>(AnyLabel.Tag.ToType<dynamic>().Item2).Show();
我的问题是,为什么第一个var不是来自类型形式而且拒绝我执行的最后一个代码部分?
答案 0 :(得分:1)
方法ToType<T>()
可能有重载版本。如果不涉及动态,编译器会在编译时解析正确的重载。如果;然而,涉及动态,绑定在运行时发生,即,在运行时使用参数的运行时类型确定正确的重载。此外,这些重载可能具有不同的返回类型。从现在开始,这个返回类型在编译时是未知的,C#编译器决定选择dynamic
作为函数的返回类型。
现在,您可以推断,您没有重载版本,可以安全地假设Form
。但是,如果您稍后添加重载会发生什么?这应该突然改变一个没有改变的表达式的返回类型吗?添加重载会导致对在编译时无法检测到的现有代码进行重大更改。
在编译时选择哪种返回类型,如果重载由运行时参数类型确定?
public static T ToType<T>(this object obj) => (T)obj;
public static int ToType<T>(this int i) => i; // Makes no sense, but valid code.
public static dynamic ToType<T>(this dynamic d) => d; // Valid as well.