4

ジェネリック メソッド内で内部コンストラクターを使用してオブジェクトを構築することは可能ですか?

public abstract class FooBase { }

public class Foo : FooBase {
   internal Foo() { }
}

public static class FooFactory {
    public static TFooResult CreateFoo<TFooResult>()
    where TFooResult : FooBase, new() {
        return new TFooResult();
    }
}

FooFactoryは と同じアセンブリにありFooます。クラスは、次のようにファクトリ メソッドを呼び出します。

var foo = FooFactory.CreateFoo<Foo>();

コンパイル時エラーが発生します。

'Foo' は、ジェネリック型またはメソッド 'FooFactory.CreateFoo()' でパラメーター 'TFooType' として使用するために、パブリック パラメーターなしのコンストラクターを持つ非抽象型である必要があります

これを回避する方法はありますか?

私も試しました:

Activator.CreateInstance<TFooResult>(); 

これにより、実行時に同じエラーが発生します。

4

4 に答える 4

5

new()制約を削除して、次を返すことができます。

//uses overload with non-public set to true
(TFooResult) Activator.CreateInstance(typeof(TFooResult), true); 

クライアントもそれを行うことができますが。ただし、これはランタイムエラーを起こしやすいです。

言語では抽象コンストラクター宣言が許可されていないため、これを安全に解決するのは難しい問題です。

于 2010-09-06T10:33:28.333 に答える
0

type引数には、 パブリックパラメーターなしのコンストラクターが必要です。他の制約と一緒に使用する場合は、new()制約を最後に指定する必要があります。

http://msdn.microsoft.com/en-us/library/d5x73970.aspx

編集:いいえ、new()制約を使用する場合、そのクラスを渡すことはできません。new()制約を使用しない場合は、リフレクションを使用して新しいインスタンスを作成してみてください。

public static TFooResult CreateFoo<TFooResult>()
where TFooResult : FooBase//, new()
        {
            return (TFooResult)typeof(TFooResult).GetConstructor(System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance, null, new Type[] {}, null).Invoke(new object[]{});
            //return new TFooResult();
        }
于 2010-09-06T10:29:03.693 に答える
0

以下のようにいくつかの回避策がありますが、その方法は必要ないと思います!

  • 型パラメーターの型に基づいてインスタンスを作成する Factory 内に switch ステートメントを配置します。

  • FooBase の各具体的な実装は、ファクトリ メソッドを渡して FooFactory に登録し、それ自体を作成します。したがって、FooFactory は内部辞書を使用します。

  • 型パラメーターと具体的な実装の間のマッピングを除いて、同様の行を拡張すると、外部コード (xml ファイル、構成など) になります。IOC/DI コンテナーもここで役立ちます。

于 2010-09-06T10:43:41.530 に答える
0
public class GenericFactory
{
    public static T Create<T>(object[] args)
    {
        var types = new Type[args.Length];
        for (var i = 0; i < args.Length; i++)
            types[i] = args[i].GetType();

        return (T)typeof(T).GetConstructor(types).Invoke(args);
    }
}
于 2011-03-02T14:22:54.903 に答える