コメントをいただきました。
以下のソースを書いていたのですが非常にまずかったようです。
private List<T> MakeList<T>(int maxRow)
{
Type type = typeof(T);
var entity = Activator.CreateInstance(type) as T;
var list = new List<T>();
for (int i = 0, i < maxRow; i++)
{
list.Add(entity);
}
return list;
}
この書き方は、極めて良くないと思います
まず、var entity = Activator.CreateInstance(type) as T;の部分ですが、Tが引数無しのコンストラクタ>が定義されていない場合、MissingMethodExceptionが飛んでくることになります。
また、list.Add(entity);としてますが、コレは結局最初作成したインスタンスの参照をすべて持たせることに>なるので、値型と、参照型で挙動に差が生まれることになり、良くないかと。
で、コメントからソースそのまま引用。
public static List<T> BuildList<T>(int maxRow) where T : new()
{
if(maxRow<0) throw new ArgumentOutOfRangeException(nameof(maxRow));
var list = new List<T>(maxRow);
for (int i = 0; i < maxRow; i++)
{
list.Add(new T());
}
return list;
}
まずLINQ使えばこんなメソッドいらなかったらしい・・・
var list = Enumerable.Range(0, 10).Select(i => (x:i, y:i + 10)).ToList();
また、Activator.CreateInstanceやnew T()などについて調べました。
Activator.CreateInstance
Acitivator.CreateInstanceメソッド
→引数なしコンストラクタのパラメータを使う前提のようです。
尚、速度的にはActivator.CreateInstanceとnew()で大差ないようで、
というのもnew T()も実は裏でActivator.CreateInstanceを使っているらしい。
ジェネリックで速度を出したければ式木が必要との事。
(といっても劇的に速くなるわけでもない)
この辺もいずれまとめようかと思います。
where句について
Tに対して、where T : new()
とすることで、
『引数なしのコンストラクタを持つT』の制約が付けれるようです。
これでコンパイルエラーにより、
Exceptionを未然に防げるセーフティな実装になるんですね。
型パラメータの制約
また、引数ありのコンストラクタ制約をつけたい場合はサポートされていない為、
これまた式木使って自前の制約を作る必要があるようです。式木難しいよね・・・
個人的には勉強になりましたがなんとも
お粗末な記事になりました・・・
参考:
.NET TIPS 文字列で指定したクラスのインスタンスを作成するには?
インスタンス生成あれこれ
インスタンスの生成速度 - Qiita