匿名类型提供了一种方便的方法,可用来将一组只读属性封装到单个对象中,而无需首先显式定义一个类型。 类型名由编译器生成,并且不能在源代码级使用。 每个属性的类型由编译器推断。

可通过使用 new 运算符和对象初始值创建匿名类型。 有关对象初始值设定项的详细信息,请参阅对象和集合初始值设定项。

以下示例显示了用两个名为 Amount 和 Message 的属性进行初始化的匿名类型。

var v = new { Amount = 108, Message = "Hello" };  
  
// 将鼠标指针停留在下面语句中的v.amount和v.message上,以验证它们的推断类型是int和string。 
Console.WriteLine(v.Amount + v.Message);

在VS中编写代码时既可以看出匿名类中的属性类型:

C#3.0新增功能02 匿名类型_C# 各版本新功能

匿名类型通常用在查询表达式的 select 子句中,以便返回源序列中每个对象的属性子集。有关查询的详细信息,请参阅 LINQ 查询表达式。

匿名类型包含一个或多个公共只读属性。 包含其他种类的类成员(如方法或事件)为无效。 用来初始化属性的表达式不能为 null、匿名函数或指针类型。

最常见的方案是用其他类型的属性初始化匿名类型。 在下面的示例中,假定名为 Product的类存在。 类 Product 包括 Color 和 Price 属性,以及你不感兴趣的其他属性。 变量 Product``products 是 对象的集合。 匿名类型声明以 new 关键字开始。 声明初始化了一个只使用 Product 的两个属性的新类型。 这将导致在查询中返回较少数量的数据。

如果你没有在匿名类型中指定成员名称,编译器会为匿名类型成员指定与用于初始化这些成员的属性相同的名称。 必须为使用表达式初始化的属性提供名称,如下面的示例所示。 在下面示例中,匿名类型的属性名称都为 Price,Color  。

var productQuery = 
    from prod in products
    select new { prod.Color, prod.Price };

foreach (var v in productQuery)
{
    Console.WriteLine("Color={0}, Price={1}", v.Color, v.Price);
}

通常,当使用匿名类型来初始化变量时,可以通过使用 var 将变量作为隐式键入的本地变量来进行声明。 类型名称无法在变量声明中给出,因为只有编译器能访问匿名类型的基础名称。 有关 var 的详细信息,请参阅隐式类型本地变量。

可通过将隐式键入的本地变量与隐式键入的数组相结合创建匿名键入的元素的数组,如下面的示例所示。

var anonArray = new[] { new { name = "apple", diam = 4 }, new { name = "grape", diam = 1 }};

特别说明

匿名类型是直接从对象派生的类类型,并且其无法强制转换为除对象外的任意类型。 虽然你的应用程序不能访问它,编译器还是提供了每一个匿名类型的名称。 从公共语言运行时的角度来看,匿名类型与任何其他引用类型没有什么不同。

通过dnSpy工具与ILDASM工具可以查看出编译器为匿名类提供的默认类名称,如下图;

C#3.0新增功能02 匿名类型_C# 各版本新功能_02

C#3.0新增功能02 匿名类型_C# 各版本新功能_03

C#3.0新增功能02 匿名类型_C# 各版本新功能_04

如果程序集中的两个或多个匿名对象初始值指定了属性序列,这些属性采用相同顺序且具有相同的名称和类型,则编译器将对象视为相同类型的实例。 它们共享同一编译器生成的类型信息。

无法将字段、属性、时间或方法的返回类型声明为具有匿名类型。 同样,你不能将方法、属性、构造函数或索引器的形参声明为具有匿名类型。 要将匿名类型或包含匿名类型的集合作为参数传递给某一方法,可将参数作为类型对象进行声明。 但是,这样做会使强类型化作用无效。 如果必须存储查询结果或者必须将查询结果传递到方法边界外部,请考虑使用普通的命名结构或类而不是匿名类型。

由于匿名类型上的 Equals 和 GetHashCode 方法是根据方法属性的 Equals 和 GetHashCode定义的,因此仅当同一匿名类型的两个实例的所有属性都相等时,这两个实例才相等。

其他技术请参阅

  • C# 编程指南
  • 对象和集合初始值设定项
  • C# 中的 LINQ 入门
  • LINQ 查询表达式

 

·

   

 个人作品

   

    1、BIMFace.Community.SDK.NET

     开源地址:https://gitee.com/NAlps/BIMFace.SDK·

·

   

    2、ZCN.NET.Common

     开源地址:https://gitee.com/NAlps/zcn.net.common

 技术栈

   

 1、Visual Studio、.C#/.NET、.NET Core、MVC、Web API、RESTful API、gRPC、SignalR、Python

 2、jQuery、Vue.js、Bootstrap

 3、数据库:SQLServer、MySQL、PostgreSQL、Oracle、SQLite、Redis、MongoDB、ElasticSearch、TiDB、达梦DM、人大金仓、 神通、南大通用 GBase、华为 GaussDB 、腾讯 TDSQL 、阿里 PolarDB、蚂蚁金服 OceanBase、东软 OpenBASE、浪潮云溪数据库 ZNBase

 4、ORM:Dapper、Entity Framework、FreeSql、SqlSugar、分库分表、读写分离

 5、架构:领域驱动设计 DDD、ABP

 6、环境:跨平台、Windows、Linux(CentOS、麒麟、统信UOS、深度Linux)、maxOS、IIS、Nginx、Apach

 7、移动App:Android、IOS、HarmonyOS、微信、小程序、快应用、Xamarin、uni-app、MUI、Flutter、Framework7、Cordova、Ionic、React Native、Taro、NutUI、Smobiler

   

 云原生、微服务、Docker、CI/CD、DevOps、K8S;

 Dapr、RabbitMQ、Kafka、分布式、大数据、高并发、负载均衡、中间件、RPC、ELK;

 .NET + Docker + jenkins + Github + Harbor + K8S;·

·

作者:张传宁   微软MCP、系统架构设计师、系统集成项目管理工程师、科技部创新工程师。

          专注于微软.NET技术(.NET Core、Web、MVC、WinForm、WPF)、通用权限管理系统、工作流引擎、自动化项目(代码)生成器、SOA 、DDD、 云原生(Docker、微服务、DevOps、CI/CD);PDF、CAD、BIM 审图等研究与应用。

          多次参与电子政务、图书教育、生产制造等企业级大型项目研发与管理工作。

          熟悉中小企业软件开发过程:需求分析、架构设计、编码测试、实施部署、项目管理。通过技术与管理帮助中小企业快速化实现互联网技术全流程解决方案。

         


         

本文版权归作者·有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。·

·