我有一个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*/ }
但是说实话我不知道哪种方法更好......
答案 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将在您访问其中一个字段时立即初始化这两个字段,这可能是不可取的。