[C#3] 3-对象和集合初始化器
1.对象初始化器
首先声明一个类Person:
public class Person { public string Name { get; set; } public int Age { get; set; } }
初始化它并调用它:
static void Main() { Person person = new Person { Name = "乱舞春秋", Age = 22 }; Console.WriteLine("姓名:{0}",person.Name); Console.WriteLine("年龄:{0}", person.Age.ToString()); }
这是编译器的一个小技巧:IL代码显示它和一般的初始化操作效果完全相同。{}里面出现的必须是共有的成员,字段或者属性。 可以支持对象初始化器的类型要满足一个条件是要有一个公有的无参的构造函数。
2.集合初始化器
static void Main() { List<Person> personList = new List<Person> { new Person { Name = "乱舞", Age = 22 }, new Person { Name = "春秋", Age = 21 } }; for (int i = 0; i < personList.Count; i++) { Console.Write(personList[i].Name+"--"); Console.WriteLine(personList[i].Age); Console.WriteLine("====================="); } }
这个有必要看看IL代码了,如下:
1 .method private hidebysig static void Main() cil managed 2 { 3 .entrypoint 4 // 代码大小 166 (0xa6) 5 .maxstack 3 6 .locals init ([0] class [mscorlib]System.Collections.Generic.List`1<class ConsoleApplication1.Person> personList, 7 [1] int32 i, 8 [2] class [mscorlib]System.Collections.Generic.List`1<class ConsoleApplication1.Person> '<>g__initLocal0', 9 [3] class ConsoleApplication1.Person '<>g__initLocal1', 10 [4] class ConsoleApplication1.Person '<>g__initLocal2', 11 [5] bool CS$4$0000) 12 IL_0000: nop 13 IL_0001: newobj instance void class [mscorlib] 14 System.Collections.Generic.List`1<class ConsoleApplication1.Person>::.ctor() 15 IL_0006: stloc.2 16 IL_0007: ldloc.2 17 IL_0008: newobj instance void ConsoleApplication1.Person::.ctor() 18 IL_000d: stloc.3 19 IL_000e: ldloc.3 20 IL_000f: ldstr bytearray (71 4E 1E 82 ) // qN.. 21 //对象初始化器_Person::set_Name 22 IL_0014: callvirt instance void ConsoleApplication1.Person::set_Name(string) 23 IL_0019: nop 24 IL_001a: ldloc.3 25 IL_001b: ldc.i4.s 22 26 //对象初始化器_Person::set_Age 27 IL_001d: callvirt instance void ConsoleApplication1.Person::set_Age(int32) 28 IL_0022: nop 29 IL_0023: ldloc.3 30 //调用List<T>的Add方法添加元素 31 IL_0024: callvirt instance void class 32 ·[mscorlib]System.Collections.Generic.List`1<class ConsoleApplication1.Person>::Add(!0) 33 //省略。。。 34 } // end of method Program::Main
从32行看得出这里主要就是这个Add方法了,以前向List中添加元素是手动调用这个方法,现在是编译器帮我们调用。集合初始化器想要编译成功,需要满足几个基本条件:
1应该实现了Icollection或者泛型版Icollection<T>接口,这样保证集合支持一个Add方法,这是理想情况下;
2实现了IEnumerable或者泛型版IEnumerable<T>接口的类型上有一个或者多个Add方法,即使没有实现1要求的接口也可以。 这是比较宽松一点的情况下;
3.总结
可以发现集合初始化器和对象初始化器的共同点是它们都是编译器做的技巧。 和以前的写法产生的效果没有任何本质区别,但是集合初始化器产生的每个对象名我们就不知道了[编译器按照它的规则产生相应的对象名,我们无法直接引用]。
作者:Blackheart
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义