C# - 匿名类型

本文关键字:类型 | 更新日期: 2023-09-12 17:38:22

在 C# 中,匿名类型是没有任何名称的类型(类),只能包含公共只读属性。它不能包含其他成员,例如字段、方法、事件等。

使用带有 object 初始值设定项语法的新运算符创建匿名类型。 隐式类型变量- var 用于保存匿名类型的引用。

下面的示例演示如何创建一个匿名类型变量student该变量包含名为 IdFirstNameLastName 的三个属性。

Example: Anonymous Type

var student = new { Id = 1, FirstName = "James", LastName = "Bond" };

匿名类型的属性是只读的,不能使用 null、匿名函数或指针类型进行初始化。可以使用点 (.) 表示法访问属性,与对象属性相同。但是,不能更改属性的值,因为它们是只读的。

Example: Access Anonymous Type

var student = new { Id = 1, FirstName = "James", LastName = "Bond" };
Console.WriteLine(student.Id); //output: 1
Console.WriteLine(student.FirstName); //output: James
Console.WriteLine(student.LastName); //output: Bond
student.Id = 2;//Error: cannot chage value
student.FirstName = "Steve";//Error: cannot chage value

匿名类型的属性可以包含另一个匿名类型。

Example: Nested Anonymous Type

var student = new { 
                    Id = 1, 
                    FirstName = "James", 
                    LastName = "Bond",
                    Address = new { Id = 1, City = "London", Country = "UK" }
                };

还可以创建匿名类型的数组。

Example: Array of Anonymous Types

var students = new[] {
            new { Id = 1, FirstName = "James", LastName = "Bond" },
            new { Id = 2, FirstName = "Steve", LastName = "Jobs" },
            new { Id = 3, FirstName = "Bill", LastName = "Gates" }
    };

匿名类型将始终是定义它的方法的本地类型。 它不能从方法返回。但是,可以将匿名类型作为对象类型参数传递给该方法,但不建议这样做。 如果需要将其传递给另一个方法,请使用结构或类而不是匿名类型。

大多数情况下,匿名类型是使用 LINQ 查询的 Select 子句创建的,以返回集合中每个对象的属性子集。

Example: LINQ Query returns an Anonymous Type

class Program
{
    static void Main(string[] args)
    {
        IList<Student> studentList = new List<Student>() { 
            new Student() { StudentID = 1, StudentName = "John", age = 18 },
            new Student() { StudentID = 2, StudentName = "Steve",  age = 21 },
            new Student() { StudentID = 3, StudentName = "Bill",  age = 18 },
            new Student() { StudentID = 4, StudentName = "Ram" , age = 20  },
            new Student() { StudentID = 5, StudentName = "Ron" , age = 21 } 
        };
        var students = from s in studentList
                       select new { Id = s.StudentID, Name = s.StudentName };
        foreach(var stud in students)
            Console.WriteLine(stud.Id + "-" + stud.Name);
    }
}
public class Student
{
    public int StudentID { get; set; }
    public string StudentName { get; set; }
    public int age { get; set; }
}

输出:

1-John
2-Steve
3-Bill
4-Ram
5-Ron

在上面的示例中,LINQ 查询中的 select 子句仅选择StudentIDStudentName属性,并将其分别重命名为 IdName。 因此,它在节省内存和不必要的代码方面很有用。 查询结果集合仅包括StudentIDStudentName属性,如以下调试视图所示。

Visual Studio 支持匿名类型的 IntelliSense,如下所示。

Visual Studio 中的匿名类型 Intellisense Support

在内部,所有匿名类型都直接派生自 System.Object 类。编译器生成一个具有某个自动生成名称的类,并根据值表达式将适当的类型应用于每个属性。 尽管您的代码无法访问它。使用GetType()方法查看名称。

Example: Internal Name of an Anonymous Type

static void Main(string[] args)
{
    var student = new { Id = 1, FirstName = "James", LastName = "Bond" };
    Console.WriteLine(student.GetType().ToString());
}