当我们不要定义复杂的方法,事件,构造函数这样复杂的类的时候,可以动态的生成一个自定义的数据类型 --> 匿名类型。

1.定义匿名类型

定义一个匿名类型时,需要用到 var 关键字和对象初始化语法。

var : 编译器会在编译时自动生成新类定义(我们无法在C#代码中看到类的名称)。

初始化:它将告诉编译器为新创建的类型创建私有的后台字段和(只读的)属性。

通过传递参数构建一个匿名类型,并打印相关信息

private static void BiuldAnonymousType(string make, string color, int currSp)
{
// 使用传入参数构建匿名类型
var car = new { Make = make, Color = color, CurrSp = currSp }; // 获取属性数据
Console.WriteLine($"{car.Color} 的 {car.Make} 时速{car.CurrSp}"); // 匿名类型包含对System.Object中每个虚方法(virtual)的自定义实现
Console.WriteLine($"ToString={car.ToString()}");
}

调用:也可以使用硬编码构建匿名类型

public static void Show()
{
Console.WriteLine("fun with anonymous types"); // 注意 匿名类型也可以使用硬编码创建
// 构建一个匿名对象表示汽车
var car = new { Make = "honda", Color = "blue", CurrSp = }; // 输出颜色和车
Console.WriteLine($"我的车是{car.Color}{car.Make}"); // 调用辅助方法通过参数创建匿名类型
BiuldAnonymousType("baoma", "white", );
}

2.匿名类型的内部表示方式

所有的匿名类型都自动继承Object,所以我们可以在 car 对象上ToString,GetHashCode,Equals,我们尝试调用一下:

private static void ReflectOverAnonymousType(object obj)
{
Console.WriteLine($"对象实例:{obj.GetType().Name}");
Console.WriteLine($"类型: {obj.GetType().Name} 基类: {obj.GetType().BaseType}");
Console.WriteLine($"toString():{obj.ToString()}");
Console.WriteLine($"getHashCode():{obj.GetHashCode()}");
}

调用以及结果:

public static void Show()
{
Console.WriteLine("fun with anonymous types"); // 构建一个匿名对象表示汽车
var car = new { Make = "honda", Color = "blue", CurrSp = }; ReflectOverAnonymousType(car);
}

car对象的类型是:<>f__AnonymousType0`3(你的或许不同),匿名类型名称由编译器觉得,我们无从干涉,CIL代码。

3.方法 ToString() 和 GetHashCode() 的实现

1.ToString()

public override string ToString()
{
StringBuilder builder = new StringBuilder();
builder.Append("{ Color = ");
builder.Append(this.<Color>i_Field);
builder.Append(", Make = ");
builder.Append(this.<Make>i_Field);
builder.Append(", CurrSp = ");
builder.Append(this.<CurrSp>i_Field);
builder.Append("}");
return builder.ToString();
}

2.GetHashCode()

它使用每个匿名类型的变量计算出散列值作为System.Collections.Generic.EqualityComparer<T>的类型输入,仅当两个匿名类型有相同的属性并且被赋予了相同的值,才会产生相同的散列值。

4.匿名类型的相等语义

Equals()

private static void EqualityTest()
{
// 构建两个匿名类型,拥有相同的名称/值对
var oneCar = new { Make = "honda", Color = "blue", CurrSp = };
var twoCar = new { Make = "honda", Color = "blue", CurrSp = }; // 调用Equals
if (oneCar.Equals(twoCar))
{
Console.WriteLine("Equals“同一个匿名对象");
}
else
{
Console.WriteLine("Equals“不是 同一个匿名对象");
} // 使用 == 操作符
if (oneCar == twoCar)
{
Console.WriteLine("==“同一个匿名对象");
}
else
{
Console.WriteLine("==“不是 同一个匿名对象");
} // 比较对象类型
if (oneCar.GetType().Name == twoCar.GetType().Name)
{
Console.WriteLine("同一个类型");
}
else
{
Console.WriteLine("不同类型");
} ReflectOverAnonymousType(oneCar);
ReflectOverAnonymousType(twoCar);
}

分析一下这样的结果:

1.Equals():编译器重写Equals()在判断对象相等时使用了基于值得语义(如:笔记两个对象的每一个数据成员的值)

2.==操作符:是因为匿名类型没有重载 相等操作符(==,!=),所以==比较的是引用,而不是内容。

3.GetType():是因为如果我们同一程序集中声明两个相同的(属性相同)匿名类型,编译器只会生成一个匿名类型的定义。

5.包含匿名类型的匿名类型

var order = new
{
car = new { Make = "honda", Color = "blue", CurrSp = },
price =
}; ReflectOverAnonymousType(order);

总结:

其实,我们应该谨慎使用匿名类型,尤其在使用LINQ时,永远不要因为匿名类型的出现而放弃使用强类型的类或结构。

其实,匿名类型本身有许多限制:

  • 你并没有控制匿名类型的名称
  • 匿名类型继承System.Object
  • 匿名类型的字段和属性总是只读的
  • 匿名类型不支持事件,自定义方法,自定义操作符和自定义重写
  • 匿名类型是隐式封闭的(implicit sealed)
  • 匿名类型的实体创建只使用默认构造函数

如果,我们需要快速定义一个实体的形状,而不需要定义其功能时,可以使用匿名类型。

学无止境,望各位看官多多指教。

C#匿名类型(Anonymous Type)学习日记的更多相关文章

  1. C#匿名类型 - Anonymous Types

    [C#匿名类型 - Anonymous Types] Anonymous types provide a convenient way to encapsulate a set of read-onl ...

  2. 无法将类型“System.Collections.Generic.List<anonymous type:string ClassID,string ClsssName>”隐式转换为“System.Collections.Generic.List<Ecology.Model.EnergyFlowGraph>”

    无法将类型“System.Collections.Generic.List<anonymous type:string ClassID,string ClsssName>”隐式转换为“Sy ...

  3. 如何把匿名类型.GetType()返回的对象传进泛型里面[转]

    //怎么取得匿名类型的Type放到 //泛型T当中?? var 匿名 = new { A = 0, B = 1 }; Type t = 匿名.GetType(); //然后下面 var xx = db ...

  4. 匿名类型 使用泛型T linq返回dynamic类型的匿名实体 如何把匿名类型.GetType()返回的对象传进泛型里面 EF实体查询出的数据List<T>转DataTable出现【DataSet 不支持 System.Nullable<>】的问题

    [100分]紧急求助:LinQ下使用IQueryable<T>如何将返回类型<T>使用匿名类型 问题描述如下:我有一个方法如下:public IQueryable Dissen ...

  5. c#匿名类 anonymous学习

    感谢http://blog.csdn.net/jjx0224/article/details/5887589 感谢http://hi.baidu.com/guodong828/blog/item/cc ...

  6. Swift编程语言学习12 ——实例方法(Instance Methods)和类型方法(Type Methods)

    方法是与某些特定类型相关联的函数.类.结构体.枚举都能够定义实例方法:实例方法为给定类型的实例封装了详细的任务与功能.类.结构体.枚举也能够定义类型方法:类型方法与类型本身相关联.类型方法与 Obje ...

  7. Python 学习日记(第三周)

    知识回顾 在上一周的学习里,我学习了一些学习Python的基础知识下面先简短的回顾一些: 1Python的版本和和安装 Python的版本主要有2.x和3.x两个版本这两个版本在语法等方面有一定的区别 ...

  8. 前端学习日记之HTML、CSS 简单总结

    前端学习日记之HTML.CSS 简单总结 标签(空格分隔): html css 前端学习日记 html超文本标记语言 一. h标题标签 h1-h7 <!DOCTYPE html> < ...

  9. c# 把一个匿名对象赋值给一个Object类型的变量后,怎么取这个变量? c# dynamic动态类型和匿名类 详解C# 匿名对象(匿名类型)、var、动态类型 dynamic 深入浅析C#中的var和dynamic

    比如有一个匿名对象,var  result =......Select( a=>new {  id=a.id, name=a.name});然后Object  obj =  result ;我怎 ...

随机推荐

  1. FC网络学习笔记01

    1.Fibre Channel 也就是“网状通道”的意思,简称FC,可以称其为FC协议.FC网络或FC互联. 2.像TCP/IP一样,FC协议集同样具备TCP/IP协议集以及以太网中的概念,比如FC交 ...

  2. AHCI vs NVMe

    http://www.hkepc.com/13139 儘管現時有不少高階 SSD 產品改用 PCIe 接口,以突破 SATA 接口的頻寬瓶頸,但控制器設計與 SATA  接口 SSD 一樣,採用老舊的 ...

  3. atlassian-jira-confluence-bitbucket破解

    ==================================================================================================== ...

  4. Shell脚本编程入门(一) 分类: 学习笔记 linux ubuntu 2015-07-09 21:06 29人阅读 评论(0) 收藏

    最近在学shell,记录一下. if语句的使用: 1.判断两个参数大小 #!/bin/sh #a test about if statement a=10 b=20 if [ $a -eq $b ]; ...

  5. Linux下搭建Oracle11g RAC(1)----IP分配与配置IP

    首先需要说明的,我的RAC搭建不是在虚拟机上完成的,而是在实际部署中,二者之间有些许差异,本人水平有限,请见谅. 其中,每台机器至少需要配置3个IP地址,在安装操作系统的过程中,我们需要配置公网IP和 ...

  6. Parallel类(简化Task 操作)

    Parallel类 Parallel类是对线程的一个很好抽象.该类位于System.Threading.Tasks命名空间中,提供了数据和任务并行性. 1.用Parallel.For()方法循环 // ...

  7. php 计算代码行数

    <?php header("Content-type:text/html;charset=utf-8"); // php 递归计算文件夹代码行数 function codeL ...

  8. java: Eclipse jsp tomcat 环境搭建(完整)

    ] 欢迎您! 要学习一门语言,首先要做的就是搭建环境,然后能写一个小的Demo(类似Helloworld),不仅可以建立信心,而且还可以为之后的学习搭建一个验证平台,事半功倍. net领域的vs,号称 ...

  9. 前台添加jquery的引用

    注意引用的顺序. 以下两个引用,因为bxCarousel.js引用了jquery.js所以jquery.js必须在bxCarousel.js的前面.一般来说对jquery.js的引用放在前面. < ...

  10. delphi 截取指定符号之间的字符串-随机读取

    unit Unit1; interface uses  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, Syste ...