C#是类型安全的编程语言。意味着所有表达式都解析成类型的实例,编译器生成的代码只执行对该类型有效的操作。dynamic的出现让C#具有了弱语言类型的特性,有利于处理需要在运行时才会知晓的信息,如果写的是纯C#应用程序,只有在使用反射的时候,才需要和运行时才能确定的信息打交道。编译器在编译的时候不再对类型进行检查,编译期默认dynamic对象支持你想要的任何特性。
var关键字和dynamic做比较。实际上,var和dynamic完全是两个概念,var实际上是编译器抛给我们的“语法糖”,一旦被编译,编译器会自动匹配var 变量的实际类型,并用实际类型来替换该变量的声明,这看上去就好像我们在编码的时候是用实际类型进行声明的。而dynamic被编译后,实际是一个object类型,只不过编译器会对dynamic类型进行特殊处理,让它在编译期间不进行任何的类型检查,而是将类型检查放到了运行期。
class Program
{
static void Main(string[] args)
{
//与var不同,声明时不需要初始化
dynamic value;
for (int i = 0; i < 2; i++)
{
value = (i == 0) ? (dynamic)12 : (dynamic)"X";
Console.WriteLine(value);
}
Console.ReadKey();
}
}

这从visual studio的编辑器窗口就能看出来。以var声明的变量,支持“智能感知”,因为visual studio能推断出var类型的实际类型,而以dynamic声明的变量却不支持“智能感知”,因为编译器对其运行期的类型一无所知。对dynamic变量使用“智能感知”,会提示“此操作将在运行时解析”。
关于dynamic变量是一个object变量这一点,可以通过IL代码得到验证。当然,编译器也对dynamic声明进行了处理,以区别直接object变量。
如果字段、方法参数或方法返回值的类型是dynamic,编译器会将类型转换为System.Object,并在元数据中间字段、参数或返回类型应用System.Runtime.CompilerServices.DynamicAttribute的实例。如果局部变量被指定为dynamic,变量类型也会成为Object,但不会向局部变量应用DynamicAttribute,因为它限制在方法内部使用。由于dynamic其实就是object,所以方法签名不能仅靠dynamic和Object的变化来区分。
所有表达式都能隐式转型为dynamic,因为所有表达式最终都生成从Object派生的类型。从Dynamic转型为其他类型时,虽然编译器允许省略显示转型,但CLR会在运行时验证转型来确定类型安全性。
{无锡人流医院哪家好 http://www.wxbhnkyy120.com/
//即将要匹配的对象
object target = "xu shuai";
//即将要匹配的参数
object arg = "shu";
//在目标上查找和希望的实参类型匹配的方法,匹配没有,则返回null
Type[] types = new Type[] { arg.GetType() };
MethodInfo method = target.GetType().GetMethod("Contains", types);
//在目标上调用方法,传递希望的实参
if (method != null)
{
object[] arguments = new object[] { arg };
Boolean res = Convert.ToBoolean(method.Invoke(target, arguments));
Console.WriteLine(res);
}
else
{
Console.WriteLine("");
}
}
{
//使用dynamic
dynamic target = "xu shuai";
dynamic arg = "shu";
Boolean re = target.Contains(arg);
Console.WriteLine(re);
}
Dynamic的一个限制是只能访问对象的实例成员,因为dynamic变量必须引用对象。但有时需要动态调用运行时才能确定的一个类型的静态成员。