3

さて、Productという抽象クラスがあります。Productを実装するItems、Kits、Packagesという3つのテーブルがあります。製品には、オブジェクトの主キーを公開するパブリックプロパティがあります。

そうは言っても、私は製品を渡すフォームを持っています。適切なテーブルを取得するために、そのタイプを反映する大きなスイッチを作成することなく、その製品を新しいデータコンテキストから引き出したいと思います。

私はこのようなことをしたかったのですが、キャストビットはfooを受け入れません。

public BuilderInclusionsForm(Product p) : this()
        {            
            Type foo = p.GetType();
            product = db2.GetTable(p.GetType()).Cast<foo>().SingleOrDefault(a => 
                a.ProductID == p.ProductID);

またはこれ:

public BuilderInclusionsForm(Product p) : this()
        {            
            Type foo = p.GetType();
            product = db2.GetTable(p.GetType()).OfType<foo>().SingleOrDefault(a => 
                a.ProductID == p.ProductID);   
4

2 に答える 2

5

いいえ、ソースコードに表示するには、コンパイル時にtype引数がわかっている必要があるためです。

BuilderInclusionsFormを製品のタイプでジェネリックにするか、次のようなジェネリックメソッドを作成できます。

private static T FindProduct<T>(T product) where T : Product
{
    return db2.GetTable(typeof(T))
                     .OfType<T>()
                     .SingleOrDefault(a => a.ProductID == p.ProductID);
}

次に、リフレクションを使用して呼び出します。

public BuilderInclusionsForm(Product p) : this()
{            
    MethodInfo method = typeof(BuilderInclusionsForm).GetMethod("FindProduct",
         BindingFlags.Static | BindingFlags.NonPublic);
    MethodInfo concrete = method.MakeGenericMethod(new Type[] { p.GetType() });
    product = (Product) concrete.Invoke(null, new object[] { p });
}

(明らかに、メソッドのオープンフォームをキャッシュすることができます。)

良くありませんが、うまくいくはずです。ただし、BuilderInclusionsFormを汎用にする方がよいと思います。常にヘルパークラスを使用できます。

public static class BuilderInclusionsForm
{
    public static BuilderInclusionsForm<T> Create<T>(T product) where T : Product
    {
        return new BuilderInclusionsForm<T>(product);
    }
}

これにより、型推論を使用できるようになります。

于 2009-01-13T14:24:06.427 に答える