.NET 中创建支持集合初始化器的类型

栏目: ASP.NET · 发布时间: 5年前

内容简介:对象初始化器和集合初始化器只是语法糖,但是能让你的代码看起来更加清晰。至少能让对象初始化的代码和其他业务执行的代码分开,可读性会好一些。本文将编写一个类型,可以使用集合初始化器构造这个类型。不只是添加元素的集合初始化器,还有带索引的集合初始化器。

对象初始化器和集合初始化器只是语法糖,但是能让你的代码看起来更加清晰。至少能让对象初始化的代码和其他业务执行的代码分开,可读性会好一些。

本文将编写一个类型,可以使用集合初始化器构造这个类型。不只是添加元素的集合初始化器,还有带索引的集合初始化器。

稍微提一下对象初始化器

很普通的类型就可以支持对象初始化器,只需要对象有可以 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 是一件非常繁琐的事情。

.NET 中创建支持集合初始化器的类型 ▲ 实现一个 ICollection 需要实现的方法

最简单的集合初始化器

只是做一个集合初始化器的话并不需要写上面那么多的代码。

实际上,你只需要两个步骤:

  1. 实现 IEnumerable 接口或任何子接口
  2. 有一个 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/"
};

这是一个可以发挥创造力的语法糖

利用单个和多个参数的集合初始化器,以及带索引的集合初始化器,我们甚至可以用集合初始化器去构造一些看起来不像集合的类型。这又是一波语法糖!

当然有一点值得注意,使用集合初始化器初始化的时候, Addthis[] 的初始化是不能同时使用的。

参考资料

事实上微软的官方文档中并没有对集合初始化器的最简实现有多少描述,所以以下的参考实际上并没有用。


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

生物序列分析

生物序列分析

Richard Durbin、Sean Eddy、Anders Krogh [等] / 王俊、郭一然、单杲 / 科学出版社 / 2010-8 / 60.00元

生物序列分析,ISBN:9787030284433,作者:(英)Durbin,R 等编著一起来看看 《生物序列分析》 这本书的介绍吧!

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具