在C#中,匿名类型是没有任何名称的类型(类),该名称只能包含公共只读属性。它不能包含其他成员,例如字段,方法,事件等。
使用带有对象初始化器语法的 new 运算符创建匿名类型。隐式类型变量 var 用于保存匿名类型的引用。
下面的示例演示如何创建一个匿名类型变量student包含名为三个属性 Id,FirstName和LastName。
var student = new { Id = 1, FirstName = "James", LastName = "Bond" };
匿名类型的属性是只读的,不能使用null,匿名函数或指针类型进行初始化。可以使用点(.)表示法访问这些属性,与对象属性相同。但是,您不能更改属性的值,因为它们是只读的。
var student = new { Id = 1, FirstName = "James", LastName = "Bond" }; Console.WriteLine(student.Id); //输出1 Console.WriteLine(student.FirstName); //输出:James Console.WriteLine(student.LastName); //输出:Bond student.Id = 2;//错误:无法更改值 student.FirstName = "Steve";//错误:无法更改值
匿名类型的属性可以包括另一个匿名类型。
var student = new { Id = 1, FirstName = "James", LastName = "Bond", Address = new { Id = 1, City = "London", Country = "UK" } };
您也可以创建一个匿名类型数组。
var students = new[] { new { Id = 1, FirstName = "James", LastName = "Bond" }, new { Id = 2, FirstName = "Steve", LastName = "Jobs" }, new { Id = 3, FirstName = "Bill", LastName = "Gates" } };
匿名类型对于定义它的方法始终是本地的。无法从方法返回。但是,匿名类型可以作为对象类型参数传递给方法,但不建议这样做。如果需要将其传递给另一个方法,请使用 struct 或 class 而不是匿名类型。
通常,使用LINQ查询的Select子句创建匿名类型,以从集合中的每个对象返回属性的子集。
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子句仅选择StudentID和StudentName属性,并将其分别重命名为Id和Name。因此,在节省内存和不必要的代码方面很有用。查询结果集合仅包含StudentID和StudentName属性,如以下调试视图所示。
Visual Studio支持IntelliSense用于匿名类型,如下所示。
在内部,所有匿名类型都直接从System.Object类派生。编译器会生成一个具有一些自动生成名称的类,并根据值表达式将适当的类型应用于每个属性。尽管您的代码无法访问它。使用GetType()方法可以查看名称。
static void Main(string[] args) { var student = new { Id = 1, FirstName = "James", LastName = "Bond" }; Console.WriteLine(student.GetType().ToString()); }