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 ;我怎 ...
随机推荐
- 国外NET 空间免费申请使用
最近研究微信公众帐号接口开发,需要使用到域名和空间,所以在度娘和谷哥的帮助下找到国外免费的空间, 刚刚注册完所以截图和大家分享下 注册地址:http://member.mywindowshosting ...
- C和指针 (pointers on C)——第四章:语句(上)
第四章--语句(上) 总结总结!!! C没有布尔类型,所以在一些逻辑推断时候必须用整型表达式,零值为假,非零值为真. for比while把控制循环的表达式收集起来放在一个地方,以便寻找. do语句比w ...
- cookie 和 HttpSession
保存会话数据的两种技术 Cookie Cookie 是客户端技术,程序把每个用户的数据以cookie的形式写给用户的浏览器.当用户使用浏览器再去访问服务器中的web资源时,就会带着各自的数据去.web ...
- Response乱码的解决方法
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletExcept ...
- InnoDB MyISAM区别及优化(摘录)
InnoDB 是 MySQL 上第一个提供外键约束的引擎,除了提供事务处理外,InnoDB 还支持行锁,提供和 Oracle 一样的一致性的不加锁读取,能增加并发读的用户数量并提高性能,不会增加锁的数 ...
- oracle数据库敏感操作前创建还原点
我们都知道,在vmware虚拟机中有一个拍摄快照的功能,我们可以把系统此时的状态保存下来,一方后面遇到不测事件,也好将系统还原,oracle中也有类似功能. 首先创建一张学生表: 向学生表中插入一条数 ...
- Android开发之Toast解析
Toast是Android系统提供的一个显示消息提示的类,它的使用非常简单,用途很广,如软件的升级,可以用它进行提示:退出程序时,也可以用它进行提醒,输入限制的提醒,等等. 使用场景: 1.需要提示用 ...
- Oracle 根据业务创建新的用户
新的需求,创建一个用户,可以查询基表的数据,但是不能修改,同时自己也可以创建对象 1.创建用户第一种方式 详细常见,前提 表空间和临时表空间必须存在 格式: create user 用户名 ident ...
- 什么是WordPress?
(今天由于好友 肖知虎的 的需求 , 我开始了帮助小虎建站的需求, 就这样开始学习了Wordpress. 这些文章就是为了记录这些我在学习过程当中的心得,和记录下来的文字而已) 什么是WordPre ...
- SQL server 跨库插入数据
1.INSERT INTO SELECT语句 语句形式为: Insert into Table2(field1,field2,...) select value1,value2,... from Ta ...