静态实例的对象引用问题

时间:2012-03-26 07:52:45

标签: c# .net

我很想知道可能在下面的代码中静态实例不为null但是MYDB类引用是由GAC处理并设置为null吗?

public class DA_Setting
{
    private static readonly DA_Setting instance = new DA_Setting();

    public static DA_Setting Instance
    {
        get { return instance; }
    }

    db MYDB = new db();

    // Some other methods here

    private void Getname()
    {
        MYDB.GetNames(); // Sometimes this line throws null reference error on LIVE server.
    }
}

3 个答案:

答案 0 :(得分:3)

GC永远不会设置 null 。周期。

如果你有一个对象的引用,那么GC的设计是为了看到你仍在使用该对象,并通过该引用保留它,因此在你完成它之前不会收集它。 / p>

MYDB字段为null的唯一方法是,如果您未能为其分配值(我可以看到您的代码中有一个初始化程序可以阻止该情况),或者如果您在代码中稍后的某个时间点为字段指定值null

我建议你将MYDB转换为get-only属性并在类构造函数中初始化它:

private DA_Setting()
{
    this.MYDB = new db();
}

public db MYDB { get; private set; }

这可以确保您无法从类外部设置此值,并且可以为您提供更具可预测性的类型。

答案 1 :(得分:1)

如果GC仍然可以访问,则GC不会收集该字段,并且可以访问该字段。我猜其他一些对象是null。您是否尝试过使用GetNames方法进入代码?

您的静态变量是GC Root,这意味着只要您的Application / AppDomain正在运行,它就不会被收集。该字段是GC根的字段,因此无法收集它。有关垃圾收集的更多信息,请参见此处:http://www.simple-talk.com/dotnet/.net-framework/understanding-garbage-collection-in-.net/

答案 2 :(得分:1)

这不应该像我理解的那样发生。静态初始化程序和构造函数在您访问静态成员之前运行 - 这是C#文档所承诺的。实例初始化程序与实例构造函数一起运行,因此如果您正在调用DA_Setting.Instance.Getname(),那么永远不应该有空引用。垃圾收集器不会随机出现并处理你仍然引用的东西,并且你肯定仍然有一个对它的引用,因为静态成员在应用程序仍然没有生命周期结束时运行

您是否检查了导致空引用异常的原因?它可能是db实例中的内容吗?