.NET 中创建支持集合初始化器的类型
对象初始化器和集合初始化器只是语法糖,但是能让你的代码看起来更加清晰。至少能让对象初始化的代码和其他业务执行的代码分开,可读性会好一些。
本文将编写一个类型,可以使用集合初始化器构造这个类型。不只是添加元素的集合初始化器,还有带索引的集合初始化器。
很普通的类型就可以支持对象初始化器,只需要对象有可以 set 的属性或者可访问的字段即可。
public class Walterlv{ public string Site { get; set; }}
初始化时可以使用
var walterlv = new Walterlv{ Site = "https://blog.walterlv.com",};
基本上大家编写的类或多或少都会支持对象初始化器,所以本文不会对此谈论更多的内容。
当你定义一个集合的时候,你会发现你的类型已经天然支持集合初始化器了。比如你定义了下面这个集合:
public class WalterlvCollection : ICollection<Walterlv>{ // 省略集合定义的代码。}
那么此集合初始化的代码就可以写成下面这样:
var collection = new WalterlvCollection{ new Walterlv(), new Walterlv(),}
实际上你会发现实现一个 ICollection 是一件非常繁琐的事情。
▲ 实现一个 ICollection 需要实现的方法
只是做一个集合初始化器的话并不需要写上面那么多的代码。
实际上,你只需要两个步骤:
实现 IEnumerable 接口或任何子接口
有一个 Add 方法
就像这样:
public class WalterlvCollection : IEnumerable{ private readonly List<Walterlv> _list = new List<Walterlv>(); public IEnumerator GetEnumerator()=>_list.GetEnumerator(); public void Add(string site) => _list.Add(new Walterlv { Site = site });}
于是你就可以像一个一般的集合那样去使用集合初始化器了:
var collection = new WalterlvCollection{ "https://blog.walterlv.com/", "https://walterlv.blog.csdn.net/",};
刚刚我们的例子中 Add 方法只有一个参数,实际上也可以是多个参数。
public class WalterlvCollection : IEnumerable{ private readonly List<Walterlv> _list = new List<Walterlv>(); public IEnumerator GetEnumerator()=>_list.GetEnumerator(); public void Add(string site, bool includeProtocol) => _list.Add(new Walterlv { Site = site });}
现在初始化的方法就有点像字典了:
var collection = new WalterlvCollection{ { "https://blog.walterlv.com/", true }, { "https://walterlv.blog.csdn.net/", true },};
当然你也可以写更多参数,看起来更加丧心病狂。
public class WalterlvCollection : IEnumerable{ private readonly List<Walterlv> _list = new List<Walterlv>(); public IEnumerator GetEnumerator()=>_list.GetEnumerator(); public void Add(string site, bool includeProtocol, string author) => _list.Add(new Walterlv { Site = site });}
var collection = new WalterlvCollection{ { "https://blog.walterlv.com/", true, "walterlv" }, { "https://walterlv.blog.csdn.net/", true, "walterlv" },};
如果你期望的初始化方法是索引,实际上也不需要 Add 方法。只需要增加一个索引的定义即可:
public class WalterlvCollection : IEnumerable{ private readonly List<Walterlv> _list = new List<Walterlv>(); public IEnumerator GetEnumerator()=>_list.GetEnumerator(); public string this[string site] { get => _list.Find(x => x.Site == site).Site; // 请忽略这里的 Bug,这只是一个语法糖的示例。 set => _list.Add(new Walterlv { Site = value }); }}
这时,可以使用索引方式的集合初始化器:
var collection = new WalterlvCollection{ ["吕毅"] = "https://blog.walterlv.com/", ["林德熙"] = "https://blog.lindexi.com/"};
利用单个和多个参数的集合初始化器,以及带索引的集合初始化器,我们甚至可以用集合初始化器去构造一些看起来不像集合的类型。这又是一波语法糖!
当然有一点值得注意,使用集合初始化器初始化的时候,Add 和 this[] 的初始化是不能同时使用的。
参考资料
事实上微软的官方文档中并没有对集合初始化器的最简实现有多少描述,所以以下的参考实际上并没有用。
英文:Object and Collection Initializers (C# Programming Guide) - Microsoft Docs
中文:对象和集合初始值设定项(C# 编程指南) - Microsoft Docs
.NET 中创建支持集合初始化器的类型相关推荐
- C#笔记13 匿名类型、集合初始化器、扩展方法和查询表达式
文章目录 匿名类型 new{...}和隐式类型var 集合初始化器和对象初始化器 扩展方法 案例引出扩展方法的意义 扩展方法的使用 做Enumerable的扩展方法 扩展方法使用 标准查询运算符 Li ...
- MAUI 中创建录音机和播放器应用
前言 在本博客中,你将了解如何在 .NET MAUI 中开发录音机和播放器.音频播放器将录制和播放音频文件. 此应用程序可以在Android和iOS上部署和使用. 预览 以下是该录音机和播放录音的应用 ...
- razor html帮助器,在 ASP.NET 网页(Razor)网站中创建和使用帮助器 | Microsoft Docs
在 ASP.NET 网页(Razor)网站中创建和使用 Helper 02/17/2014 本文内容 本文介绍如何在 ASP.NET 网页(Razor)网站中创建帮助程序. 帮助器是一种可重用的组件, ...
- [From 10.1~10.5] 对象和集合初始化器(C#语法糖系列)
经常要构造一个对象并设置对象的一些公众属性(或字段). 1.为了简化这个常见的编程模式,C#语言支持一种特殊的对象初始化语法.下面是一个例子: Employee e = new Employee(){ ...
- 【Flutter】Dart 数据类型 Map 类型 ( 创建 Map 集合 | 初始化 Map 集合 | 遍历 Map 集合 )
文章目录 一. Dart 数据类型 Map 类型 二. Map 类型初始化并赋值 1. 创建 Map 对象同时进行初始化操作 2. 先创建 Map 对象再进行赋值 三. Map 集合遍历 1. 使用 ...
- lambda 对象初始化器 集合初始化器
- dotNet中初始化器的使用
dotNet中初始化器的使用 2013年12月7日 13:27 有两类初始化器: 对象初始化器和集合初始化器 比如现在有一个User类: Public class User { public in ...
- Linq之隐式类型、自动属性、初始化器、匿名类
目录 写在前面 系列文章 隐式类型 自动属性 初始化器 匿名类 总结 写在前面 上篇文章是本系列的小插曲,也是在项目中遇到,觉得有必要总结一下,就顺手写在了博客中,也希望能帮到一些朋友.本文将继续介绍 ...
- 第七节:语法总结(1)(自动属性、out参数、对象初始化器、var和dynamic等)
一. 语法糖简介 语法糖也译为糖衣语法,是由英国计算机科学家彼得·约翰·兰达(Peter J. Landin)发明的一个术语,指计算机语言中添加的某种语法,这种语法对语言的功能并没有影响,但是更方 ...
最新文章
- 主板上来了一个新邻居,CPU 慌了!
- html5开发之viewport使用
- 科普MinGW MinGW-W64
- leetcode算法题--设计链表
- Redis 高可用特性之 “持久化” 详解
- 使用 C++0x 时 make_shared 完美转发构造函数参数的测试编译器
- c#进阶(2)—— ASP.NET MVC 常用路由总结
- 解决:VMware DHCP Service 服务无法启动
- Spring Cloud Alibaba —— Nacos Config 配置中心
- Spark MLlib垃圾邮件分类示例
- z77主板可以用nv_刚和吧友讨论了z77加装nvme固态的问题。在这重开一帖。
- sp3485调试:sp3485-TTL转max485模块-TTL转usb模块电脑pc
- Bluemix RSA Private key cannot be used to encrypt
- 高通量基因组测序中,什么是测序深度和覆盖度?
- radio按扭设置只读_关于html:为什么单选按钮不能为“只读”?
- oracle中字体倒转,Oracle特殊查询 行列倒转 分页
- poi实现多线程大数据导出
- iOS面试:简历模版(A4纸正反两面)
- 群接龙小程序定制开发
- C/C++中的exit()函数