C#匿名类型(Anonymous Type)学习日记
当我们不要定义复杂的方法,事件,构造函数这样复杂的类的时候,可以动态的生成一个自定义的数据类型 --> 匿名类型。
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)学习日记的更多相关文章
- C#匿名类型 - Anonymous Types
[C#匿名类型 - Anonymous Types] Anonymous types provide a convenient way to encapsulate a set of read-onl ...
- 无法将类型“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 ...
- 如何把匿名类型.GetType()返回的对象传进泛型里面[转]
//怎么取得匿名类型的Type放到 //泛型T当中?? var 匿名 = new { A = 0, B = 1 }; Type t = 匿名.GetType(); //然后下面 var xx = db ...
- 匿名类型 使用泛型T linq返回dynamic类型的匿名实体 如何把匿名类型.GetType()返回的对象传进泛型里面 EF实体查询出的数据List<T>转DataTable出现【DataSet 不支持 System.Nullable<>】的问题
[100分]紧急求助:LinQ下使用IQueryable<T>如何将返回类型<T>使用匿名类型 问题描述如下:我有一个方法如下:public IQueryable Dissen ...
- c#匿名类 anonymous学习
感谢http://blog.csdn.net/jjx0224/article/details/5887589 感谢http://hi.baidu.com/guodong828/blog/item/cc ...
- Swift编程语言学习12 ——实例方法(Instance Methods)和类型方法(Type Methods)
方法是与某些特定类型相关联的函数.类.结构体.枚举都能够定义实例方法:实例方法为给定类型的实例封装了详细的任务与功能.类.结构体.枚举也能够定义类型方法:类型方法与类型本身相关联.类型方法与 Obje ...
- Python 学习日记(第三周)
知识回顾 在上一周的学习里,我学习了一些学习Python的基础知识下面先简短的回顾一些: 1Python的版本和和安装 Python的版本主要有2.x和3.x两个版本这两个版本在语法等方面有一定的区别 ...
- 前端学习日记之HTML、CSS 简单总结
前端学习日记之HTML.CSS 简单总结 标签(空格分隔): html css 前端学习日记 html超文本标记语言 一. h标题标签 h1-h7 <!DOCTYPE html> < ...
- c# 把一个匿名对象赋值给一个Object类型的变量后,怎么取这个变量? c# dynamic动态类型和匿名类 详解C# 匿名对象(匿名类型)、var、动态类型 dynamic 深入浅析C#中的var和dynamic
比如有一个匿名对象,var result =......Select( a=>new { id=a.id, name=a.name});然后Object obj = result ;我怎 ...
随机推荐
- varchar(n)和varchar(max)有什么区别
如果列数据项的大小一致,则使用 char. 如果列数据项的大小差异相当大,则使用 varchar. 如果列数据项大小相差很大,而且大小可能超过 8,000 字节,请使用 varchar(max).
- FastDFS、nginx配置手记
第一部分 FastDFS介绍 1.FastDFS是什么 FastDFS是一款类Google FS的开源分布式文件系统,它用纯C语言实现,支持Linux.FreeBSD.AIX等UNIX系统.它只能 ...
- Android开发_后台任务task管理_allowTaskReparenting alwaysRetainTaskState clearTaskOn
1.android:allowTaskReparenting 这个属性用来标记一个Activity实例在当前应用退居后台后,是否能从启动它的那个task移动到有共同affinity的task,“tru ...
- android 77 fragment
fragment是3.0之后才有的,之前平板是3.0专用,后来手机和平板都用3.0 Activity: package com.itheima.fragment; import android.os. ...
- 运行codeblocks时出现的问题解决
When I try running Code::Blocks, I get the following error message: Another program instance is alre ...
- hdu2007
import java.util.*;class Main{public static void main(String args[]){Scanner cin=new Scanner(System. ...
- WebService学习笔记系列(一)
webservice主要是解决两个系统或者两个应用程序之间的远程调用,它提供了一种通过web方式访问的api,调用是跨语言.跨平台的. webservice的客户端与服务端进行交互的时候使用xml来传 ...
- [学习笔记]设计模式之Bridge
写在前面 为方便读者,本文已添加至索引: 设计模式 学习笔记索引 “魔镜啊魔镜,谁是这个世界上最美丽的人?”月光中,一个低沉的声音回荡在女王的卧室.“是美丽的白雪公主,她正和小霍比特人们幸福快乐地生活 ...
- compareTo()
从字面意思可知这个方法就是比较的意思. 所以该方法有如下两种情况: 1.比较前后的两个字符不相同: (1) String str = "Hello World"; Stri ...
- VS2010调试多进程--医疗His调试中使用
有些时候碰到自己开发的程序嵌入到别人的框架中,而在接口的地方出了问题,而又不方便将自己的模快加入到别人的工程中这个时候VS的附加到进程调试变得不可或缺了,直奔主题 http://msdn.micros ...