静态字段或属性是否初始化一次

本文关键字:一次 初始化 字段 属性 是否 静态 | 更新日期: 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; }
}