У меня есть модульные тесты, в которых я устанавливаю свойство на ресурсе в деструкторе класса как true, но он бросает нулевую ссылку excpetion. ресурс предоставляется классу и все еще имеет ссылку на вызывающего.Destructor throws System.NullReferenceException
Тесты модуля проходят, но в консоли отображается исключение 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; }
}
Unit Test
[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 никогда не называется вызываемым значением. destructor/finalize вызывается только один раз, но вопрос все еще остается там, почему он в первую очередь ошибся, если?
~Foo()
{
if(Resource != null)
{
Console.Write("releasing");
resource.Release = true;
} else
{
Console.Write("this never gets executed");
}
}
Они называются ** Финализаторы **, не деструкторы. Финализаторы должны использоваться с неуправляемыми ресурсами. Ни 'Resource', ни' Foo', кажется, неуправляемы. Финализаторы являются неопределенными и, возможно, являются причиной вашей проблемы. – pinkfloydx33
жаль, что я новичок в этом, какая разница между управляемыми и неуправляемыми ресурсами, а также что я могу сделать, чтобы исправить код? – user2727195
@ pinkfloydx33 - Я тоже предпочитаю термин финализатор, но, к сожалению, [C# Programming Guide] (https://msdn.microsoft.com/en-us/library/66x5fx1b.aspx) не согласен с терминологией. –