C# 懒惰<;T>;vs静态ctor(防止onbeforefieldinit)?
我有一个DAL基本类(数据访问),它有两个成员:C# 懒惰<;T>;vs静态ctor(防止onbeforefieldinit)?,c#,.net-4.0,static,lazy-evaluation,C#,.net 4.0,Static,Lazy Evaluation,我有一个DAL基本类(数据访问),它有两个成员: /*1*/ class BaseDal /*2*/ { /*3*/ static DatabaseProviderFactory factory = new DatabaseProviderFactory(); /*4*/ static SqlDatabase sqlServerDB = factory.Create("ExampleDatabase") as SqlDatabase; /
/*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行
请注意,我不需要创建新的MyCustomerDal,因为我不需要实例,只需要使用方法GetData()
(static
)。另外,这两行可以服务于所有派生类
我的问题是:
我希望这两个初始值设定项(第3,4行)是laze initialize
我有两个选择:
选项1
我可以设置一个静态ctor,这基本上意味着这些成员只有在访问类时才会运行(beforefieldinit
issue)
选项2
我可以使用Lazy
:(+属性)
/*1*/Lazy myDb=new Lazy(()=>factory.Create(“ExampleDatabase”)作为SqlDatabase);
/*2*/
/*3*/受保护的SqlDatabase Mydb
/*4*/ {
/*5*/get{return myDb.Value;}
/*6*/ }
但说实话,我不知道哪种方法更好……根据您的评论更新 我建议你读一读他的文章 在您的案例中,似乎最好的方法也是最明确的。使用懒惰 你的第一种方法更糟 3:如果标记为BeforeFieldInit,则类型的初始值设定项方法将在首次访问任何静态字段时或之前执行 为该类型定义的 4:如果未标记BeforeFieldInit,则该类型的初始值设定项方法将在处执行(即,由以下项触发): a。首次访问该类型的任何静态字段,或 b。第一次调用该类型的任何静态方法,或 c。第一次调用该类型的任何实例或虚拟方法(如果是值类型或 d。第一次调用该类型的任何构造函数
因此,如果类型标记为BeforeFieldInit或未标记为BeforeFieldInit,那么使用Lazy比第一种方法更好。我认为应该使用
静态Lazy
字段(可以选择添加静态属性来访问Lazy值,正如您所做的那样)
这样,您就可以在不需要实例的情况下使用它们,并且具有完全惰性的行为
您的选项1将在访问其中一个字段时立即初始化这两个字段,这可能是不可取的。我看不出它与我的选项1有什么不同。而BDW,他的最后一个样本确实使用了LAZY。如果您有其他静态字段,那么这个示例不是很有用。因为如果你触摸其他的,那些(我们谈论的)将会自动填充。我们不希望这样。你可能已经看到或知道了,但为了以防万一,看看这篇文章,如果不知道beforefieldinit陷阱,我就不会写这个问题了……:-)好的,对不起,我的最后一张照片:),在这篇文章的最后一个例子中,我仍然需要静态cTOR,因为我们仍然在做
新的懒惰(东西)
。。。。这样,它将是完全满的:-)……p.s。确保初始化解决此问题。是否要延迟初始化Lazy
对象?是的,我需要。创建惰性对象需要新的Lazy(),它也应该是惰性的。阅读有关解决此问题的LazyInitializer.EnsureInitialized方法的信息。(或者在这里添加静态ctor-也可以实现同样的效果)。谢谢,我并没有仔细看LazyInitializer。请注意,如果使用静态的惰性的,则会固有地处理多线程问题。使用LazyInitializer
,您应该使用重载来初始化ref bool
,这样您就不会浪费时间初始化多个对象。总的来说,我会选择Lazy
,因为简单,而且单个“Lazy”的开销可以忽略不计。
/*1*/ Lazy<SqlDatabase> myDb = new Lazy<SqlDatabase>(() => factory.Create("ExampleDatabase") as SqlDatabase);
/*2*/
/*3*/ protected SqlDatabase Mydb
/*4*/ {
/*5*/ get { return myDb.Value; }
/*6*/ }