0

2 つのメンバーを持つDAL基本クラス ( data access ) があります。

/*1*/    class BaseDal
/*2*/       {
/*3*/           static DatabaseProviderFactory factory = new DatabaseProviderFactory();
/*4*/           static SqlDatabase sqlServerDB = factory.Create("ExampleDatabase") as SqlDatabase;
/*5*/       }
/*6*/   
/*7*/   
/*8*/   subclasses : 
/*9*/   
/*10*/    class MyCustomerDal:BaseDal
/*11*/       {
/*12*/          ...
/*13*/          ...
/*14*/          public static DataTable GetData()
/*15*/            {
/*16*/             // do something....
/*17*/            }
/*18*/   
/*19*/       }
/*20*/   

私の質問は、行 3,4 についてです。

new MyCustomerDalインスタンスを必要とせず、メソッドGetData()( ) を使用するためだけに作成していないことに注意してくださいstatic。また、これらの 2 行はすべての派生クラスを提供できます。

そして、ここに私の質問があります:

これらの 2 つのイニシャライザ (3,4 行目) を遅延初期化する必要があります。

私には2つのオプションがあります:

オプション1

基本的に、クラスがアクセスされたときにのみこれらのメンバーが実行されることを意味する静的ctorを設定できます(beforefieldinit問題)。

オプション 2

Lazy:(+property)を使用できます

/*1*/   Lazy<SqlDatabase> myDb = new Lazy<SqlDatabase>(() => factory.Create("ExampleDatabase") as SqlDatabase);
/*2*/   
/*3*/           protected SqlDatabase Mydb 
/*4*/           {
/*5*/               get { return myDb.Value; }
/*6*/           }

しかし、正直なところ、どちらのアプローチが優れているかはわかりません....

4

2 に答える 2

1

フィールドを使用する必要があると思いますstatic Lazy<T>(オプションで静的プロパティを追加して、遅延値にアクセスします)。

このようにして、インスタンスを必要とせずにそれらを使用でき、完全に遅延した動作もできます。

オプション 1 では、いずれかのフィールドにアクセスするとすぐに両方のフィールドが初期化されますが、これはおそらく望ましくありません。

于 2013-07-12T21:55:49.407 に答える
1

あなたのコメントに基づいて更新されました

Implementing the Singleton Pattern in C# (Jon Skeet 著)と彼の記事C# and beforefieldinitを読むことをお勧めします。

あなたの場合の最良のアプローチは、最も明示的でもあるようです。Lazy< T > を使用します。

あなたの最初のアプローチはもっと悪いです。ECMA-335 第 6 版 / 2012 年 6 月 (共通言語インフラストラクチャ (CLI) パーティション I から VI、p. 43-44) :

3: BeforeFieldInit とマークされている場合、型の初期化メソッドは、その型に定義された静的フィールドへの最初のアクセス時、またはその前の時点で実行されます。

4: BeforeFieldInit がマークされていない場合、その型の初期化メソッドが実行されます (つまり、トリガーされます):

を。そのタイプの静的フィールドへの最初のアクセス、または

b. そのタイプの静的メソッドの最初の呼び出し、または

c. 値型または値型の場合、その型のインスタンスまたは仮想メソッドの最初の呼び出し

d. その型のコンストラクターの最初の呼び出し。

したがって、型が BeforeFieldInit とマークされている場合でも、BeforeFieldInit とマークされていない場合でも、最初のアプローチよりもLazy< T > を使用する方が適切です。

于 2013-07-12T21:34:57.297 に答える