Anonymous Type, Implicitly typed arrays, Collection initializers
C# 3.0 の Anonymous Type かつ Implicitly typed arrays という組み合わせで,毎回フィールド名を書かされるのは面倒,という話.
var accessCounts = new[] { new { Month = new DateTime(2007, 1, 1), Total =25558, Unique = 18492}, new { Month = new DateTime(2007, 2, 1), Total =24414, Unique = 18754}, new { Month = new DateTime(2007, 3, 1), Total =29179, Unique = 22874}, new { Month = new DateTime(2007, 4, 1), Total =25899, Unique = 20326}, new { Month = new DateTime(2007, 5, 1), Total =22937, Unique = 18568}, new { Month = new DateTime(2007, 6, 1), Total =26170, Unique = 20914}, new { Month = new DateTime(2007, 7, 1), Total =29543, Unique = 23153}, new { Month = new DateTime(2007, 8, 1), Total =33943, Unique = 26098}, new { Month = new DateTime(2007, 9, 1), Total =25392, Unique = 19601}, new { Month = new DateTime(2007, 10, 1), Total =33216, Unique = 25343}, new { Month = new DateTime(2007, 11, 1), Total =39775, Unique = 29982}, new { Month = new DateTime(2007, 12, 1), Total =36918, Unique = 27737}, };
まあ確かにそうかも.とはいえこういうのはもはや手書きはしないよなぁとか,コード生成ルールを弄るのが正解かもという気もちらり,と.
とりあえず対応策.Add(DateTime month, int total, int unique) というメソッドを持ち,IEnumerable<T> を実装した型 X があれば,Collection initializers が使えるようになるのでもうちょっと簡単に書けるはず.というわけでいくつかヘルパークラスを書いてみました.
使い方はこんな感じ.
static class Program { static void Main(string[] args) { var accessCounts = new TupleList<DateTime, int, int> { { new DateTime(2007, 1, 1), 25558, 18492}, { new DateTime(2007, 2, 1), 24414, 18754}, { new DateTime(2007, 3, 1), 29179, 22874}, { new DateTime(2007, 4, 1), 25899, 20326}, { new DateTime(2007, 5, 1), 22937, 18568}, { new DateTime(2007, 6, 1), 26170, 20914}, { new DateTime(2007, 7, 1), 29543, 23153}, { new DateTime(2007, 8, 1), 33943, 26098}, { new DateTime(2007, 9, 1), 25392, 19601}, { new DateTime(2007, 10, 1), 33216, 25343}, { new DateTime(2007, 11, 1), 39775, 29982}, { new DateTime(2007, 12, 1), 36918, 27737}, }.Select((Month, Total, Unique) => new { Month, Total, Unique }); foreach (var item in accessCounts) { Console.WriteLine("{0} {1} {2}", item.Month, item.Total, item.Unique); } } }
本体はこちら.
using System; using System.Collections.Generic; public partial struct Tuple<TArg1, TArg2> { public readonly TArg1 Arg1; public readonly TArg2 Arg2; public Tuple(TArg1 arg1, TArg2 arg2) { this.Arg1 = arg1; this.Arg2 = arg2; } } public partial struct Tuple<TArg1, TArg2, TArg3> { public readonly TArg1 Arg1; public readonly TArg2 Arg2; public readonly TArg3 Arg3; public Tuple(TArg1 arg1, TArg2 arg2, TArg3 arg3) { this.Arg1 = arg1; this.Arg2 = arg2; this.Arg3 = arg3; } } public partial struct Tuple<TArg1, TArg2, TArg3, TArg4> { public readonly TArg1 Arg1; public readonly TArg2 Arg2; public readonly TArg3 Arg3; public readonly TArg4 Arg4; public Tuple(TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4) { this.Arg1 = arg1; this.Arg2 = arg2; this.Arg3 = arg3; this.Arg4 = arg4; } } public sealed partial class TupleList<TArg1, TArg2> : List<Tuple<TArg1, TArg2>> { public void Add(TArg1 arg1, TArg2 arg2) { this.Add(new Tuple<TArg1, TArg2>(arg1, arg2)); } public IEnumerable<TResult> Select<TResult>(Func<TArg1, TArg2, TResult> selector) { return this.Select(item => selector(item.Arg1, item.Arg2)); } } public sealed partial class TupleList<TArg1, TArg2, TArg3> : List<Tuple<TArg1, TArg2, TArg3>> { public void Add(TArg1 arg1, TArg2 arg2, TArg3 arg3) { this.Add(new Tuple<TArg1, TArg2, TArg3>(arg1, arg2, arg3)); } public IEnumerable<TResult> Select<TResult>(Func<TArg1, TArg2, TArg3, TResult> selector) { return this.Select(item => selector(item.Arg1, item.Arg2, item.Arg3)); } } public sealed partial class TupleList<TArg1, TArg2, TArg3, TArg4> : List<Tuple<TArg1, TArg2, TArg3, TArg4>> { public void Add(TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4) { this.Add(new Tuple<TArg1, TArg2, TArg3, TArg4>(arg1, arg2, arg3, arg4)); } public IEnumerable<TResult> Select<TResult>(Func<TArg1, TArg2, TArg3, TArg4, TResult> selector) { return this.Select(item => selector(item.Arg1, item.Arg2, item.Arg3, item.Arg4)); } }