読者です 読者をやめる 読者になる 読者になる

【C#】ジェネリック引数付きコンストラクタ

C#では テンプレート型のコンストラクタに引数が渡せません

using System;
public class Foo<T> where T : new()
{
    public Foo()
    {
        new T(1);
    }
}
`T': cannot provide arguments when creating an instance of a variable type
詳細:Compiler Error CS0417

Type.GetConstructor 使用すれば解決可能です

using System;
public static class Generic
{
    public static T Construct<T,P1>(P1 p1)
    {
        return (T)typeof(T).GetConstructor(new Type[]{typeof(P1)}).Invoke(new object[]{p1});
    }
}
public class Bar
{
    public Bar(int val){}
}
public class Foo<T>
{
    public Foo()
    {
        Generic.Construct<T,int>(val);
    }
}

可変長引数&引数3個までの Generic.Construct 作成してみた

using System;
public static class Generic
{
    // Param:params
    public static T Construct<T,P1>(params P1[] p1)
    {
        return (T)typeof(T).GetConstructor(new Type[]{typeof(P1[])}).Invoke(new object[]{p1});
    }
    // Param:0
    public static T Construct<T>() where T : new()
    {
        return new T();
    }
    // Param:1
    public static T Construct<T,P1>(P1 p1)
    {
        return (T)typeof(T).GetConstructor(new Type[]{typeof(P1)}).Invoke(new object[]{p1});
    }
    // Param:2
    public static T Construct<T,P1,P2>(P1 p1,P2 p2)
    {
        return (T)typeof(T).GetConstructor(new Type[]{typeof(P1),typeof(P2)}).Invoke(new object[]{p1,p2});
    }
    // Param:3
    public static T Construct<T,P1,P2,P3>(P1 p1,P2 p2,P3 p3)
    {
        return (T)typeof(T).GetConstructor(new Type[]{typeof(P1),typeof(P2),typeof(P3)}).Invoke(new object[]{p1,p2,p3});
    }
}

こんな感じ使います

// 可変長引数
Params param = Generic.Construct<Params,int>(0,1,2,3,4,5,6,7,8,9);
// 引数1個
Param1 param_int = Generic.Construct<Param1,int>(0);
// 引数2個
Param2 param2 = Generic.Construct<Param2,int,string>(0,"Hello");

参考したサイト:
引数付きコンストラクタをジェネリックな関数で呼び出す - in the box
[C#]引数付きコンストラクタのインスタンスをgenericで生成 · GitHub

  • 追記

20160422
【C#】ジェネリック引数付きコンストラクタ 2 - 浮遊島