在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
让我们快速看看object关键字先。我不会对它讲太多,因为它在C#1.0就已经有了。这个关键字没有更多东西除了作为System.Object的快捷方式,System.Object是C#类层次的根类型。(然而,正如Eric Lippert在他博客中指出,并非一切类型都继承源于object[中][英])这是一个强大的机制,这样你几乎可以分配任何实例值到此类型。 object obj = 10; Console.WriteLine(obj.GetType()); // 输出 System.Int32 因为 // 这是这个对象里存储的值的类型。 // 一个编译错误, 因为 // 在编译时obj的类型是System.Object。 // obj = obj + 10; // 你需要显式转换obj到期望的类型。 obj = (int)obj + 10; // 然而, 这样并不表示你真的安全。 // 你可能转换到一个错误的类型 // 而编译器并不会发现。 // 这里你会在运行时得到一个异常, // 因为obj是int类型,不是string类型。 // obj = (string)obj + 10; // 如果你将其转换到一个错误的数值类型, // 你也会得到一个运行时异常 // 虽然有隐式转换的语法在这里。 // obj = (double)obj + 10;
新的dynamic关键字来了。它告诉编译器不要强制附加规则在你的代码上。
dynamic dyn = 10; Console.WriteLine(dyn.GetType()); // 跟"object"一样. // 输出 System.Int32 因为 // 这是这个对象里存储的值的类型。 // 没有编译错误,因为 // 编译器不会在编译时 // 试图识别dynamic对象的类型。
// 同样,这个操作会在所有数值或 // 其他支持“+”操作符的类型上成功运算。 dyn = 10.0; dyn = dyn + 10; dyn = "10";
这是一个object和dynamic间的主要区别----用dynamic相当于你告诉编译器此对象的类型只在运行时确定,编译器不会试图干预。最终,你可以写更少的代码。但我要强调一下,相对于使用原有的object关键字,这样做不会增加任何危险。同样,也不会减少任何危险,所以当操作任何对象需要类型检查技术时(如反射),则使用dynamic对象会更好。 让我们假设拥有一个简单方法。
public static void Print(string arg)
现在我们看看你能怎么传递dynamic对象给它。
dynamic dyn = 10; // 你将于运行时在这里得到一个异常.
你可以看见,虽然编译器允许你传递一个dynamic对象给你的方法,但你的方法永远不会得到这个对象如果它是个错误的类型。在方法实际执行之前已经有一个异常抛出。只有当它包含一个恰当值时,你才能传递dynamic对象给你的方法,在这里是string类型。
再次强调,这跟你使用object关键字相比不会有太多行为上的区别。
//Print(obj); // 编译, 但这里在运行时会有个异常。 //Print((string)obj); // 这里的代码会正常工作,因为现在obj是个string型, // 但你不需要转换。 obj = "10";
有人说(int)obj这种写法并不难理解,为什么要再来个dynamic呢?好吧,有些情况下你不得不执行较多的转换操作,这使得你的代码很难理解。还有些情况下简单的转换并不能达到目的,你需要调用反射方法,比如InvokeMember或GetProperties。一个很好的例子便是COM互操作,这就是为什么它要修改以使用新dynamic特性(更多信息点这里“how-to”)。 使用var关键字申明变量,编译器会根据分配的实例类型确定此变量的类型,即类型推断。
Console.WriteLine(va.GetType()); // 输出 System.Int32 因为 // 这是这个对象里存储的值的类型。 // 而va的编译时类型也已经被编译器确定为int型。 // 没有编译错误,因为 // va在第一句赋值时 // 便被编译器确定其类型是int。 va = va + 10; // 编译错误,因为 // va变量已经确定是int型,而10.0是double型, // 且double型向int型不可隐式转换。
跟object比,var属于强类型; 跟dynamic比,var并无任何运行时的动态特性,仅仅是编译器在编译时反向推断其类型,同直接用其编译时类型声明变量功能上是一样的。它仅仅是编译器提供的语法糖。dynamic可不是语法糖,dynamic是需要运行时支持的。
VAR 是3.5新出的一个定义变量的类型 1. 必须在定义时初始化。也就是必须是var s = “abcd”形式,而不能是如下形式: var s; s = “abcd”; 2. 一但初始化完成,就不能再给变量赋与初始化值类型不同的值了。 3. var要求是局部变量。 4. 使用var定义变量和object不同,它在效率上和使用强类型方式定义变量完全一样。
1.COM对象 2.动态语言(如IronPython,IronRuby等)对象 3.反射对象 4.C# 4.0中动态创建的对象 |
2023-10-27
2022-08-15
2022-08-17
2022-09-23
2022-08-13
请发表评论