Lazy <t> vs static ctor(阻止onbeforefieldinit)?</t>

时间:2013-07-12 21:26:27

标签: c# .net-4.0 static lazy-evaluation

我有一个DAL 基础类(数据访问),它有2个成员:

/*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行可以为所有派生类提供服务。

这是我的问题:

我希望这两个初始值设定项(第3,4行)为laze初始化。

我有两个选择:

选项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*/           }

但是说实话我不知道哪种方法更好......

2 个答案:

答案 0 :(得分:1)

根据您的评论更新

我建议您阅读Implementing the Singleton Pattern in C# (by Jon Skeet)及其文章C# and beforefieldinit

在您的情况下,最好的方法似乎也是最明确的。使用Lazy&lt; T &gt;。

你的第一种方法更糟糕。 ECMA-335 6th Edition / June 2012 (Common Language Infrastructure (CLI) Partitions I to VI, p. 43-44)

  

3:如果标记为BeforeFieldInit,则在首次访问任何静态字段时或之前执行类型的初始化方法   为该类型定义。

     

4:如果没有标记为BeforeFieldInit,则执行该类型的初始化方法(即由其触发):

     

一个。首先访问该类型的任何静态字段,或

     

湾首次调用该类型的任何静态方法,或

     

℃。如果是值类型或

,则首先调用该类型的任何实例或虚方法      

d。首次调用该类型的任何构造函数。

因此,使用Lazy&lt; T &gt;如果类型标记为BeforeFieldInit或未标记为BeforeFieldInit,则优于第一种方法。

答案 1 :(得分:1)

我认为您应该使用static Lazy<T>字段(可选择使用添加的静态属性来访问延迟值)。

这样,您可以在不需要实例的情况下使用它们,并且还具有完全惰性的行为。

您的选项1将在您访问其中一个字段时立即初始化这两个字段,这可能是不可取的。