泥庭

2016年10月28日

[C#読書会]コレクションの初期化構文

Filed under: .NET, C#, 読書会 — yone64 @ 1:30 午前
前回の続きです。今回は4.4。
コレクション初期化子を使おうというお話。

コレクション初期化子は積極的に使うべきだと思うのですが、書き方には自由度があって好みが分かれるところもあるかな?という気がします。
var list = new List<string> // コンストラクタ呼び出しの()は省略可能
{
    "Alpha",
    "Beta",
    "Gamma", // 最後の項目の後に[,]を付けてもエラーにならない
};
まず、引数なしのコンストラクタ呼び出しの()は省略できます。個人的には必ず省略しますが、この書籍的には必ず記述してますね。(ショートコードなのに…)
次に、初期化子の最後の項目の後に[,]がついててもエラーになりません。
もちろん書かない方が1文字短いのですが、個人的には書く方が好きです。理由は、コピペベースで項目を増減させたときに楽というのと、項目の追加修正を行ったときにソース管理上、差分が発生する行が減るからです。(完全に好みですw)

書籍の解説の中にも出てきてるのですが、配列の初期化と似て非なる部分も多いです。
配列はいろいろ特別扱いされている感が強いですね。
var array1 = new int[3] { 1, 2, 3, };
var array2 = new int[] { 1, 2, 3, };     // 要素数の指定は省略可能
var array3 = new[] { 1, 2, 3, };         // 配列の型の指定は省略可能
int[] array4 = { 1, 2, 3, };             // 左辺の宣言からの型推論も可能

var list = List<int> { 1, 2, 3, };        // 必ず<T>の指定は必要。
要素数の指定はListだから関係ないとしても、ListのT型を{}の中の項目から推論したり、左辺から型を推論したりといった初期化はできません。
ただし、オブジェクト初期化子と併用する場合だけ、ちょっと特別に解決します。((あまり知られてない気もします。
// こんなクラスがあった時
class MyClass
{
    public string Name { get; set; }
    public List<int> List1 { get; set; }
    public List<int> List2 { get; } = new List<int>();
}
// オブジェクト初期化子を伴う初期化で
var m = new MyClass
{
    Name = "名前",
    List1 = new List<int> { 1, 2, 3, }, // 新しいインスタンスを生成して代入
    List2 = { 1, 2, 3, },               // 既存のListに対してAdd
};
Addの呼び出しに展開される。ってことをきちんと理解してると、そんなに変な感じでもないですか?

その他、C#6でコレクション初期化子周辺が少し強化されていますので、利用できるところでは利用していきたいですね。
# インデクサによる初期化子はまだ使いたいと思う場面に出会ったことはないですが…
拡張メソッドでコレクション初期化子
http://ufcpp.net/study/csharp/ap_ver6.html#add-extensions

コメントする »

まだコメントはありません。

RSS feed for comments on this post. TrackBack URI

コメントを残す

WordPress.com Blog.