.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 中创建支持集合初始化器的类型的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: NET Core微服务之路:实战SkyW
- 下一篇: 为什么我的会话状态在ASP.NET Co