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

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. varchar(n)和varchar(max)有什么区别

    如果列数据项的大小一致,则使用 char. 如果列数据项的大小差异相当大,则使用 varchar. 如果列数据项大小相差很大,而且大小可能超过 8,000 字节,请使用 varchar(max).

  2. FastDFS、nginx配置手记

    第一部分   FastDFS介绍 1.FastDFS是什么 FastDFS是一款类Google FS的开源分布式文件系统,它用纯C语言实现,支持Linux.FreeBSD.AIX等UNIX系统.它只能 ...

  3. Android开发_后台任务task管理_allowTaskReparenting alwaysRetainTaskState clearTaskOn

    1.android:allowTaskReparenting 这个属性用来标记一个Activity实例在当前应用退居后台后,是否能从启动它的那个task移动到有共同affinity的task,“tru ...

  4. android 77 fragment

    fragment是3.0之后才有的,之前平板是3.0专用,后来手机和平板都用3.0 Activity: package com.itheima.fragment; import android.os. ...

  5. 运行codeblocks时出现的问题解决

    When I try running Code::Blocks, I get the following error message: Another program instance is alre ...

  6. hdu2007

    import java.util.*;class Main{public static void main(String args[]){Scanner cin=new Scanner(System. ...

  7. WebService学习笔记系列(一)

    webservice主要是解决两个系统或者两个应用程序之间的远程调用,它提供了一种通过web方式访问的api,调用是跨语言.跨平台的. webservice的客户端与服务端进行交互的时候使用xml来传 ...

  8. [学习笔记]设计模式之Bridge

    写在前面 为方便读者,本文已添加至索引: 设计模式 学习笔记索引 “魔镜啊魔镜,谁是这个世界上最美丽的人?”月光中,一个低沉的声音回荡在女王的卧室.“是美丽的白雪公主,她正和小霍比特人们幸福快乐地生活 ...

  9. compareTo()

    从字面意思可知这个方法就是比较的意思. 所以该方法有如下两种情况: 1.比较前后的两个字符不相同: (1)     String str = "Hello World"; Stri ...

  10. VS2010调试多进程--医疗His调试中使用

    有些时候碰到自己开发的程序嵌入到别人的框架中,而在接口的地方出了问题,而又不方便将自己的模快加入到别人的工程中这个时候VS的附加到进程调试变得不可或缺了,直奔主题 http://msdn.micros ...