0

非常に単純なジェネリック コンストラクター メソッドがあります。

public T Instance<T, TT>(TT parms) where T : class
{
    return (T)Activator.CreateInstance(typeof(T), new[] { parms });
}

次のようなメソッドを呼び出すと:

Instance<MyClass, string>("SomeStringValue").Customers.Where(x => x.Id == Id).Select(p => blah..blah...blah;

「System.MissingMethodException: 型「MyClass」のコンストラクターが見つかりません。System.RuntimeType.CreateInstanceImpl (BindingFlags bindingAttr、バインダー バインダー、オブジェクト [] 引数、CultureInfo カルチャで...'

bindingflags などを追加しようとしましたが、うまくいきませんでした。

基本的に、引数を使用してオブジェクトをインスタンス化しようとしています。問題なくオブジェクトを明示的に宣言できます。

var myObj = new MyClass("SomeStringValue");

しかし、ジェネリック コンストラクターを使用する必要があります。

私が欠けているものを誰かが明確にすることができますか?

EDIT 完全なプログラム (簡略化)。

public abstract class A 
{
    public T Instance<T, TT>(TT parms) where T : class
    {
       return (T)Activator.CreateInstance(typeof(T), new[] { parms });
    }
}

public class B 
{
    public B(string someValue)
    {
        var myValue = someValue;
    }
}

public class C
{
  public void DoStuff()
  {
     var x = Instance<B, string>("SomeStringValue");
  }
}

私がやろうとしていることです。

4

2 に答える 2

1

Activator<T>.CreateInstance()呼び出そうとしているオーバーロードには、 type の 2 番目の引数が必要ですObject[]。作成する新しい配列はTT[]. TTクラス型に制約されている場合、aTT[]はパラメーターを満たす可能性がありObject[]ます。TT[]ただし、制約のないジェネリックは として使用できませんObject[]。コンパイラは、TT[]を として渡すことができないと判断するとObject[]、(paramsオーバーロードの 2 番目のパラメーターの仕様のため)、渡す 2 番目のパラメーターが として修飾されているかどうかを確認しますObject。すべての配列は から派生するためObject、そうなります。したがって、コンパイラは、型Objectを保持する単一要素の配列を作成します。TT[]を期待するコンストラクターがないためObject[]、呼び出しは失敗します。

この問題を回避したい場合は、新しいObject[]を作成するのではなく、適切なパラメータを含む新しい を作成しTT[]ます。それはあなたの問題を解決するはずです。

于 2012-12-04T20:41:05.963 に答える
-1

以下に示すように、クラスBのコンストラクターを変更します。

public B(object someValue)
    {
        var myValue = someValue;
    }

コードが正しく機能し始めます。

于 2012-12-04T20:38:18.093 に答える