静态字段或属性是否初始化一次
本文关键字:一次 初始化 字段 属性 是否 静态 | 更新日期: 2023-09-27 18:16:28
使用下面的代码,将每个调用到Test。someBaseField或Test。someBaseProperty导致函数被调用和SomeBase的新实例被创建?还是只在开始时发生一次?
我该如何设置后者(在开始时调用一次)?
public class SomeBase {}
public class SomeObjectA : SomeBase {}
public class SomeObjectB : SomeBase {}
public class Test
{
public static bool someBool = true;
public static SomeBase someBaseField = GetBase(someBool);
public static SomeBase someBaseProperty { get { return GetBase(someBool); } }
public static SomeBase GetBase(bool getA)
{
if(getA)
return new SomeObjectA() as SomeBase;
else
return new SomeObjectB() as SomeBase;
}
}
getbase每次都会被调用,并且每次都会返回一个新的somebase实例。你在那里做的事叫做工厂。
你要做的是创建一个单例。有许多方法可以创建单例,但最流行的是跟踪一些字段或属性,并在每次初始化时返回它们,如果没有初始化则初始化。
所以你要做的是:
static someBase _trackingVar;
public static someBase someProperty{
get
{
if(_trackingVar == null){
_trackingVar = GetBase(...);
}
return _trackingVar;
}
}
这种方法的一个问题是它不是线程安全的。这种创建单例的方法有一个线程安全的版本。详见http://msdn.microsoft.com/en-us/library/ff650316.aspx
每次调用"new"都会创建一个类"SomeBase"的新实例。因此,在您的示例中,这两行将创建两个新实例。
public static SomeBase someBaseField = GetBase(someBool);
public static SomeBase someBaseProperty { get { return GetBase(someBool); } }
请注意,在这两种情况下,您只是将引用作为静态的。静态引用对对象的创建没有影响。
如果你只想创建一个对象,使用私有文件:
private static SomeBase _someBaseField = null;
在GetBase()中添加空检查,如下所示:
if (_someBaseField == null)
{
_someBaseField = new SomeObjectA() as SomeBase;
return _someBaseField;
}
else
{
return _someBaseField;
}
你可以选择改变someBaseProperty,这样你也可以在内部使用属性setter。
public static SomeBase someBaseProperty
{
get { return GetBase(someBool); }
private set(value) { _someBaseField = value; }
}