析构函数抛出System.NullReferenceException

时间:2017-02-01 12:50:00

标签: c# garbage-collection

我已经进行了单元测试,我在类的析构函数中将资源的属性设置为true,但它会抛出null引用excpetion。资源提供给类,但仍然引用了调用者。

单元测试正在通过,但我在控制台中看到NullReferenceException,行号指向析构函数中的行。

class Resource
{
    public bool Release { get; set; } = false;
}

正在考试的课程

class Foo
{
    public Foo()
    {
    }

    ~Foo()
    {
        Resource.Release = true; // error points to this line
    }

    public Resource Resource { get; set; }
}

单元测试

    [TestMethod]
    public void TestRelease()
    {
        Foo foo = new Foo();
        Resource resource = new Resource();
        foo.Resource = resource;

        Assert.IsTrue(resource.Release == false, "Expecting resource.Release == false");

        foo = null;
        System.GC.Collect();
        System.GC.WaitForPendingFinalizers();

        Assert.IsNotNull(resource, "Expecting resource is not null");
        Assert.IsTrue(resource.Release == true, " Expecting resource.Release == true");

    }

错误

System.NullReferenceException: Object reference not set to an instance of an object.
at Foo.Finalize()

修改 - 这解决了问题,但不知道为什么?

有趣的是我添加了这一行,现在没有更多的错误。 else子句永远不会被调用意味着析构函数/ finalize只被调用一次,但问题仍然存在,为什么它首先抛出错误而没有?

    ~Foo()
    {
        if(Resource != null)
        {
            Console.Write("releasing");
            resource.Release = true;
        } else
        {
            Console.Write("this never gets executed");
        }

    }

1 个答案:

答案 0 :(得分:1)

以下是使用Foo模式重新实现的IDisposable课程:

class Foo : IDisposable
{
    public Foo()
    {
    }

    public void Dispose()
    {
        Resource.Release = true;
    }

    public Resource Resource { get; set; }
}