C# 匿名类型、var 和 dynamic 的演进史

作者:微信公众号:【架构师老卢】
2-18 15:49
21

概述:#1 历史随着C#的发展,语言的内容不断丰富,开发变得更加方便快捷,C#的锐度无疑显露出来。C# 语言自诞生以来一直是一种强类型语言。这种性质今天没有改变,我认为将来也不会改变。由于它是一种强类型语言,因此编写任何程序都需要满足以下基本条件:变量声明必须指明其类型变量类型清除后,运行时无法更改其类型。代码显示如下:public  class Student  {         public string Name { get; set; }         public int Age { get; set; }         public string Like { get; s

#1 历史

随着C#的发展,语言的内容不断丰富,开发变得更加方便快捷,C#的锐度无疑显露出来。C# 语言自诞生以来一直是一种强类型语言。这种性质今天没有改变,我认为将来也不会改变。由于它是一种强类型语言,因此编写任何程序都需要满足以下基本条件:

  1. 变量声明必须指明其类型

  2. 变量类型清除后,运行时无法更改其类型。

代码显示如下:

public  class Student  
 {  
        public string Name { get; set; }  
        public int Age { get; set; }  
        public string Like { get; set; }  
 }  
  
  
static void Main(string\[\] args)  
{  
    int a = 10;  
    string s = "abc";  
    Student student = new Student();  
    // a compilation error occurs below. The variable type cannot be changed after it is declared.  
    s = a;  
    student = s;  
    a = 10.1f;  
}  

但是,在实际开发中,我们经常会遇到以下常见问题:

1.在较大的程序中,只有一个或几个地方(不超过3个地方)需要使用某种类型或某些类型(如上面的学生),其他地方不再需要这些类型。单独声明 Student 类型,使用此类型时所需的代码量可能会超过代码量,并且投资产出比不划算。

2.在一个程序中,只需要某种类型对象的某些属性或方法就可以参与操作。在这种情况下,将这种类型的对象临时转换为具有程序所需的某些属性和方法的对象可以使程序更加精简。

3.其他情况...

以上实际 C# 开发中的常见问题在 JavaScript 开发中都有更好的解决方案,如下所示:

//You need to simulate a student object in js here  
student = {"name":"Zhang San","age":20,"like":"LOL"};  
//You need to simulate a teacher object in js here  
teacher = {"name":"Teacher Li","like":"Confiscate the student's mobile phone and LOL yourself"};  
//Here you need to convert the student into an object with only name and age.  
person = {"name":student.name,"age":student.age};

#2 匿名对象(匿名类型)

C# 在 3.0 版中吸收了 JavaScript 脚本语言的语法优势,并对 C# 进行了相应的升级,使其也支持这种语法形式(C# 仍然是一种强类型语言)。示例代码如下:

static void Main(string[] args)  
{  
     new {Name="Jhon",Age=20,Like="LOL"};  
}

上面的 C# 代码告诉编译器通过 new 关键字创建对象。该对象有三个属性:Name、Age 和 Like,后跟 = 和属性的相应值。这样就避免了“创建对象必须首先有对象类型的约束”,因此在开发过程中我们不再需要为较少使用的类型创建单独的类,解决了上面提到的问题 1。

现在创建的对象不指定特定类型,因此称为匿名对象。

#3 无值

虽然我们不知道编译器生成的类型名称,但我们可以让编译器根据编译结果推断变量类型。此时,var 关键字开始发挥作用:

static void Main(string[] args)  
{  
     var x = new {Name="Jhon",Age=20,Like="LOL"};  
}

使用 var 的注意事项:

1. var 只能在方法中声明局部变量

2.用var声明的变量的类型在赋值后确定,其他类型的值不能在后续程序中赋值。

3. var x = new object() 没意义,不要写这样的代码......

现在,有了对匿名对象和 var 推断类型的支持,我们可以处理上面提到的问题 2。示例代码如下:

static void Main(string[] args)  
{  
 var x = new { Name = "Jhon", Age = 20, Like = "LOL" };  
 var s = new { Name = x.Name, Age = x.Age };  
}

以上只是例子。如果您熟悉 Linq 或 Entity Framework,那么与问题 2 相对应的用法将是压倒性的......

#4 动态类型

匿名类型的使用通常仅限于方法的局部范围,这意味着它们是动态定义的,一旦使用就会消失。在以下情况下应该怎么做?

static void Main(string[] args)  
 {  
      var x = GetObject();   
 }  
  
 private static XXX GetObject()  
 {  
      return new { Name = "Jhon", Age = 20, Like = "LOL" };  
 }

通过使用 GetObject 方法返回匿名对象,无法确定返回值的类型名称。在这里,暂时使用 xxx 作为占位符。在返回的类型不确定的情况下,可以使用它来指示它。例如:dynamic

static void Main(string[] args)  
{  
    var x = GetObject();   
    Console.WriteLine(x.Name);  
}  
  
private static dynamic GetObject()  
{  
    return new { Name = "Jhon", Age = 20, Like = "LOL" };  
}

在这种情况下,该方法不会导致语法错误,并且程序可以成功编译和执行。那么,究竟该怎么做才能使程序成功编译呢?dynamic

#5 的作用dynamic

  1. dynamic表示动态类型,这意味着类型不是在程序的编写和编译阶段确定的,而是在运行时通过反射来确定相关对象的属性或方法。因此,在编写阶段没有语法检查。
  2. dynamic可用于声明字段、属性、方法参数和方法返回值。
  3. dynamic不支持 IntelliSense,因为在代码编写期间,在运行时(反射)之前无法知道所表示的内容。dynamic

声明的变量可以理解为 类型的变量。因此,将任何类型的值分配给变量都是有效的。但是,当使用变量访问特定属性值或调用方法时(此时,程序肯定处于运行时状态),公共语言运行时 (CLR) 将检查(使用反射)被调用的属性或方法是否存在。如果不存在,则会引发运行时异常。dynamicobjectdynamic

相关留言评论
昵称:
邮箱:
阅读排行