在理解 var 和 dynamic 关键字之前, 让我们先了解一下编程语言的类别.
C# 中有两类编程语言:
静态类型语言类别
动态语言类别
静态类型语言
静态类型语言也被称为强类型语言. 所谓强类型语言, 通俗的讲, 就是在编译过程中执行类型检查的语言. 我们举个简单的例子, 比如我们知道一个方法的返回类型, 但是如果返回类型过于复杂, 那么我推荐你使用 var. 但是, 当你明确知道返回类型时, 或者返回的只是简单类型, 那么我推荐你直接使用该数据类型来声明方法返回类型, 就像平时我们经常用 string,int,bool 等修饰符声明返回类型一样.
接下来让我们来了解 C# 中的 var 关键字.
var 关键字是定义数据类型的间接方式
当你定义特定类型的 var 时:
string str = "Test";
这种写法被称为显式类型的声明, 也被称为直接声明.
当你使用 var 关键字定义一个变量时:
var str = "Test";
这被称为隐式类型声明或间接类型声明.
一般情况下, 编译器会在编译过程中验证数据, 并在编译过程中创建适当的类型. 在此实例中, 编译器将检查 Test, 并在生成 IL 代码时将 var 关键字替换为字符串.
var 关键字在编译时静态的定义数据类型, 而不是在运行时, 即: 一旦定义了数据类型, 它将不会在运行时更改.
让我们看下面的例子:
- var str = "Test";
- str = 123;
生成这个应用程序, 如下图所示, 将在 str = 123 处的隐式转换抛出编译错误
如果将鼠标移动到第一行的 str 上, 实际上是可以获得局部变量字符串 str 的值, 如下图所示
我们可以通过使用 ILDasm.exe 打开这个 exe/dll 来验证这个结果.
何时使用 var
对于像 int,double,string 等简单数据类型, 我们最好使用特定的数据类型来声明变量, 以免让事情变得复杂. 但当你创建了一个很大的类, 那么为了方便创建对象, 你最好使用 var 关键字. 还有一种约定俗成的习惯, 当我们使用 LINQ 或 Anonymous 类型时, 必须使用 var 关键字.
动态类型语言
动态类型语言是指在运行时执行类型检查的语言. 如果您不知道您将获得或需要分配的值的类型, 则在此情况下, 类型是在运行时定义的. 让我们看看下面的例子.
- class Program {
- static void Main(string[] args)
- {
- dynamic str = "Test";
- }
- }
现在, 如果您输入 str., 那么您将无法获得任何智能提示, 如下图所示.
此例中, 在为 str 分配值之后, 如果执行一些数学运算, 它不会给出任何错误信息.
- class Program {
- static void Main(string[] args)
- {
- dynamic str = "Test";
- str++;
- }
- }
很明显, 现在就算我生成应用程序, 也不会有错误产生, 应用程序也会成功生成:
但是, 如果你运行这个应用程序, 对不起, VS 会给你如下所示的运行时错误:
dynamic 关键字内部使用反射, 感兴趣的童鞋可以自行研究一下.
小结
var 和 dynamic 关键字之间的主要区别在于绑定时间不一样: var 是早期绑定, dynamic 绑定则会在运行时进行.
var 实际上是编译器抛给我们的语法糖, 一旦被编译, 编译器就会自动匹配 var 变量的实际类型, 并用实际类型来替换该变量的声明, 等同于我们在编码时使用了实际类型声明. 而 dynamic 被编译后是一个 Object 类型, 编译器编译时不会对 dynamic 进行类型检查.
.Net 4.0 之前的运行时的动态调用一般是通过反射来实现, 但是反射的代码的可读性不高..Net 4.0 之后使用 dynamic 就好得多, 因为 dynamic 是一种静态类型, 完全可以像其它类型一样的声明和调用, 而不用写反射相关的代码.
合理的运用 dynamic 可以让你的代码更加的简洁, 而且比直接使用反射性能更好 (反射没有优化处理的前提), 因为 dynamic 是基于 DLR, 第一次运行后会缓存起来. 其实有心的同学会发现. net 的类库里面很多地方都用了 dynamic 这个东西, 例如: mvc 中的 ViewBag 就是一个很好的例子. 一般情况下, 如果开发者不知道方法和方法的返回类型是否公开, 请使用 dynamic 关键字.
来源: https://www.cnblogs.com/yayazi/p/8998610.html