c#でジェネリッククラスの静的メソッドにアクセスする

c# generics inheritance methods static

私はコードに次のような状況があります。

私はクラスがあります:

抽象クラスDataAccessBase:IDataAccessここでT:AnotherAbstractClass

このクラス `DataAccessBase`には、whichステートメントのenum値を使ってそれ自身の派生クラスのインスタンスを作成する静的ファクトリメソッドもあり、どの派生型を作成するかを決定します。

static IDataAccess CreateInstance(TypeToCreateEnum)

さて、 `DataAccessBase`から派生した型はそれ自体一般的なものではなく、Tの型を指定します。

クラスPoLcZoneData:DataAccessBase // PoLcZoneはAnotherAbstractClassから派生しています。

今のところこれが総称の有効利用の限界を押し広げているのかどうかはわかりませんが、最初に静的な `CreateInstance()`メソッドにアクセスする方法が本当に心配です。

現時点でこれを行っている方法は、T: `AnotherAbstractClass`の場合、単純に任意の型Tを渡すことです。 特に私は `AnotherAbstractClass`自体を渡しています。 これでコンパイルはうまくできますが、静的型にするためだけに任意の型をジェネリッククラスに渡すのは少し厄介です。

DataAccessBase`は継承チェーンの下位レベルであるため、実際には状況を多少単純化しましたが、静的ファクトリメソッドは中間層に存在し、 PoLcZoneData`のようなクラスが最も一般的でない唯一のレベルで派生しています。

この取り決めについての人々の考えは何ですか?

  4  0


ベストアンサー

あなたは同じ名前の非ジェネリッククラスを持つことが許されています…​ おそらく何かのように:

抽象クラスDataAccessBase:IDataAccessここでT:AnotherAbstractClass {... 静的クラスDataAccessBase {public static IDataAccess CreateInstance(TypeToCreateEnum){...}}

これで、余分な T`を使わずに DataAccessBase.CreateInstance`を使うことができます。 通常、あなたは DataAccessBase`から DataAccessBase`の internal`メソッドを呼び出すかもしれません - あなたのシナリオでは多少の反映/ MakeGenericType`も必要かもしれませんが。

9


私はしばらく前に似たような問題(「静的メソッドをオーバーロードする方法」)に出くわし、それをReflectionで解決しました。

これが私の状況です:

1) public abstract class AuditObject:ActiveRecordBase(はい、私はActiveRecordを使用しています)そして

2) public class Employee:AuditObject

どちらも静的メソッドをいくつか定義しています。

public static DataTable GetLookupTable(String where、Int32 topRows){return doExtremelyCleverStuffToFetchData(where、topRows); }

(#2では `public new static`が必要です。そうでなければコンパイラの警告が出ます)

コードがそうであるように、私が呼び出すと

DataTable myList = AuditObject.GetLookupTable( "inactive = 0"、100);

…​and T is Employee, the static method is not “overriden” i.e. the one
実行されるのは(2)ではなく(1)の方法です。

そのため、(1)では、静的メソッド(この例ではGetLookupTable)を次のように変更しました。

public static DataTable GetLookupTable(String where、Int32 topRows){DataTable tbl = null;

ブールhasOverride = hasMethodOverride( "GetLookupTable");

DataTableとしてのif(hasOverride){tbl = invokeStaticMethod( "GetLookupTable"、new Object [2] {where、topRows})。 } else {tbl = doExtremelyCleverStuffToFetchData(ここで、topRows); }

tblを返します。 }

静的メソッドが存在するかどうかを調べる方法は次のとおりです。

private static Boolean hasMethodOverride(String methodName){var methodQuery = from typeof(T)のメソッド.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.InvokeMethod)where method.Name == methodName select method;

methodQuery.Count()> 0を返します。 }

そして、これが “override”メソッドの呼び出し方法です。

public static Object invokeStaticMethod(String MethodName、Object [] Args){return typeof(T).InvokeMember(MethodName、BindingFlags.Public | BindingFlags.Static | BindingFlags.InvokeMethod、null、null、Args);} }

ほら! `DataTable myList = AuditObject.GetLookupTable(” inactive = 0 “、100);`を呼び出し、TがEmployeeの場合、Employeeクラスで定義された静的メソッドから結果が得られます。

お役に立てれば、

ディミトリス

2


私はその設計に何か問題があるとは思わない。特に実装の詳細を指定するためにtemplateパラメータを使用しているのであれば。 私が提案するのは、単純にファクトリ関数を静的にするのではなく、単なるスタンドアロンにすることです。 それは私のためにそれに取り組むための最も明快な方法でしょう。

何らかの方法でカプセル化したい場合は、名前空間、または命名規則をお勧めします。

さらに別の解決策は、DataAccessBaseのタイプを次のように定義して、現在行っていることを隠すことです。

typedef DataAccessBase DataAccessBaseFactory;

これは私の最もお勧めできない解決策ですが、絶対にそれを望むならCreate関数を静的なままにします。

0


タイトルとURLをコピーしました