web-dev-qa-db-ja.com

C#新規作成T()

次のコードで私がやろうとしている(しかし失敗している)ことを確認できます。

protected T GetObject()
{
    return new T();
}

どんな助けも大歓迎です。

編集:

コンテキストは次のとおりです。標準化されたメソッドを使用して、派生するすべてのコントローラーのカスタムコントローラークラスをいじっていました。そのため、コンテキストでは、コントローラータイプのオブジェクトの新しいインスタンスを作成する必要がありました。そのため、執筆時点では次のようなものでした。

public class GenericController<T> : Controller
{
    ...

    protected T GetObject()
    {
        return (T)Activator.CreateInstance(ObjectType);
    }        

    public ActionResult Create()
    {
        var obj = GetObject()

        return View(obj);
    }

そして、ここで反射が最も簡単だと思いました。質問の最初の声明を考えると、正解としてマークするのに最も適切な答えはnew()制約を使用するものであったことに同意します。私はそれを修正しました。

142
Hanshan

新しい制約 を見てください

public class MyClass<T> where T : new()
{
    protected T GetObject()
    {
        return new T();
    }
}

Tは、デフォルトのコンストラクターを持たないクラスである可能性があります。この場合、new T()は無効なステートメントになります。 new()制約は、Tにデフォルトのコンストラクターが必要であり、new T()が有効であることを示しています。

同じ制約をジェネリックメソッドに適用できます。

public static T GetObject<T>() where T : new()
{
    return new T();
}

パラメーターを渡す必要がある場合:

protected T GetObject(params object[] args)
{
    return (T)Activator.CreateInstance(typeof(T), args);
}
370
Alex Aza

なぜActivator.CreateInstanceが提案されていないのですか?

http://msdn.Microsoft.com/en-us/library/wccyzw83.aspx

T obj = (T)Activator.CreateInstance(typeof(T));
56
Steve

別の方法は、リフレクションを使用することです:

protected T GetObject<T>(Type[] signature, object[] args)
{
    return (T)typeof(T).GetConstructor(signature).Invoke(args);
}
28
Sean Thoman

完了のために、ここでの最良の解決策は、多くの場合、ファクトリー関数の引数を要求することです。

T GetObject<T>(Func<T> factory)
{  return factory(); }

次のように呼び出します:

string s = GetObject(() => "result");

必要に応じて、これを使用して、使用可能なパラメーターを要求または使用できます。

18
Joel Coehoorn

新しい制約 は問題ありませんが、Tも値型である必要がある場合は、これを使用します。

protected T GetObject() {
    if (typeof(T).IsValueType || typeof(T) == typeof(string)) {
        return default(T);
    } else {
       return (T)Activator.CreateInstance(typeof(T));
    }
}
14
Lukas Cenovsky

これはC#4のタグが付けられているため、オープンソースフレームワーク ImpromptuIntereface を使用すると、dlrを使用してコンストラクターを呼び出します。ただし、主な利点は、C#4.0オプションパラメータを持つコンストラクタを正しく処理できることです。これは、Activatorではできません。

protected T GetObject(params object[] args)
{
    return (T)Impromptu.InvokeConstructor(typeof(T), args);
}
7
jbtule

これを取得するには、次のコードを試しました:

  protected T GetObject<T>()
    {
        T obj = default(T);
        obj =Activator.CreateInstance<T>();
        return obj ;
    }
4
UJS