匿名类型只能用var声明,本质是编译器生成的只读类,作用域限于当前方法,属性名大小写敏感且不可修改,相等性基于所有属性值但数组等引用类型不深度比较。

匿名类型只能用 var 声明,不能显式写类型名
匿名类型的本质是编译器自动生成的只读类,没有公开的类型名。试图写 AnonymousType x = new { Name = "a", Age = 25 }; 会编译失败——AnonymousType 根本不存在。必须用 var 让编译器推断类型:var person = new { Name = "a", Age = 25 };
常见错误:在方法返回值、字段或参数中尝试使用匿名类型,比如 public {string Name} GetData() 或 private {int Id} _cache;,这些全部非法。匿名类型作用域仅限于当前方法内,且不能跨方法传递(除非转成 object,但会丢失编译时成员访问能力)。
属性名和类型由初始化表达式决定,大小写敏感且不可修改
写 new { Name = "Tom", age = 18 } 会生成两个属性:Name(string)和 age(int),注意 age 是小写,调用时也必须写 obj.age,写 obj.Age 就报错 CS1061 'object' does not contain a definition for 'Age'。
以下情况会触发新类型生成(即两个匿名对象不兼容):
- 属性名顺序不同:
new { A = 1, B = 2 }和new { B = 2, A = 1 }是不同类型 - 属性名相同但类型不同:
new { X = 5 }(int) vsnew { X = 5L }(long) - 一个带属性,一个不带:
new { Id = 1 }和new { Id = 1, Name = "x" }
可安全用于 LINQ 查询投影,但慎用于跨方法或序列化
匿名类型最自然的使用场景是 LINQ 的 Select 投影,例如:
var result = users.Where(u => u.IsActive)
.Select(u => new { u.Id, u.Name, IsAdult = u.Age >= 18 });
这时 result 是 IEnumerable,每个元素都是同一匿名类型,可正常遍历和访问属性。
千博购物系统.Net能够适合不同类型商品,为您提供了一个完整的在线开店解决方案。千博购物系统.Net除了拥有一般网上商店系统所具有的所有功能,还拥有着其它网店系统没有的许多超强功能。千博购物系统.Net适合中小企业和个人快速构建个性化的网上商店。强劲、安全、稳定、易用、免费是它的主要特性。系统由C#及Access/MS SQL开发,是B/S(浏览器/服务器)结构Asp.Net程序。多种独创的技术使
但要注意:
- 不能直接 JSON 序列化(如
JsonSerializer.Serialize(obj)可能抛NotSupportedException,取决于序列化器配置) - 反射获取属性需用
obj.GetType().GetProperties(),不能硬编码类型 - 若需跨方法传参,应改用元组(
(string Name, int Age))、记录类型(record)或普通类
Equals 和 GetHashCode 基于所有属性值,但不支持 null 安全比较
两个匿名对象只要所有属性名、类型、值都相同,== 或 .Equals() 就返回 true。例如:
var a = new { X = 1, Y = "hello" };
var b = new { X = 1, Y = "hello" };
Console.WriteLine(a.Equals(b)); // true
但一旦任一属性为 null,且另一方对应属性是非空引用类型,比较仍成立;而如果双方都是 null,也没问题。真正容易出错的是嵌套匿名类型或含数组时——数组本身不会被深度比较,new { Data = new[] { 1, 2 } }.Equals(new { Data = new[] { 1, 2 } }) 返回 false,因为数组引用不同。
所以别依赖匿名类型的相等性做关键逻辑判断,尤其涉及集合去重或缓存键计算时,优先用明确的 record 或自定义 IEquatable 实现。








