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

时间:2014-08-05 03:14:07

标签: c# properties static initialization field

使用下面的代码,每次调用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;
    }
}

2 个答案:

答案 0 :(得分:3)

每次为任一属性调用get base时,每次都会返回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

答案 1 :(得分:1)

每次致电" 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,以便您也可以在内部使用属性设置器。

public static SomeBase someBaseProperty 
{
    get { return GetBase(someBool); }
    private set(value) { _someBaseField = value; }
}

没有必要将Filed公开为公开。