我有这样的课。 (这只是示例)
public class NewTest
{
public int I { get; set; }
public NewTest()
{
I = 10;
throw new ApplicationException("Not Possible");
}
}
现在,如果我使用这样的课程
NewTest t = new NewTest();
在上面的行中,作为NewTest构造函数抛出异常变量t永远不会像constuctor之前那样分配任何值,它会抛出异常,但是根据测试以及每个其他问题(Why throwing exception in constructor results in a null reference?)创建对象。
现在这个对象是在Heap中创建的,但是它不包含任何根变量以供参考,所以它是否会为垃圾收集创建问题?或是内存泄漏了什么?
以下示例帮我清除了我的困惑。 另一个例子
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
NewMethod();
System.GC.Collect();
Console.WriteLine("Completed");
Console.ReadLine();
}
private static void NewMethod()
{
Object obj = null;
try
{
Console.WriteLine("Press any key to continue");
Console.ReadLine();
NewTest t = new NewTest(out obj);
}
catch
{
Console.WriteLine("Exception thrown");
}
try
{
Console.WriteLine("Press any key to continue");
Console.ReadLine();
NewTest1 t = new NewTest1();
}
catch
{
Console.WriteLine("Exception thrown");
}
Console.WriteLine("Press any key to continue");
Console.ReadLine();
System.GC.Collect();
Console.WriteLine("Press any key to continue");
Console.ReadLine();
}
}
public class NewTest1
{
public int I { get; set; }
public NewTest1()
{
I = 10;
throw new ApplicationException("Not Possible");
}
}
public class NewTest
{
public int I { get; set; }
public NewTest(out Object obj)
{
obj = this;
I = 10;
throw new ApplicationException("Not Possible");
}
}
}
答案 0 :(得分:8)
其他答案是正确的;我将向他们添加一个有趣的事实,即最终化的对象,其构造函数抛出仍然是最终的。这意味着终结器可以对构造函数未正常完成的对象进行操作。 终结器不能假定对象在完成时初始化。这是为什么很难写出正确的终结器的另一个原因。
答案 1 :(得分:3)
在构造函数中抛出异常对垃圾收集器来说不是问题,它肯定不会导致内存泄漏。
虽然从堆中分配的内存永远不会进入您的程序,但它可用于运算符new
的内部实现,它负责确保新创建的实例符合垃圾回收条件。< / p>
答案 2 :(得分:1)
如果从逻辑上看,null只是您的引用可能具有的值。您的代码等于
NewTest t = null;
t = new NewTest();-> the assignment never occurs because you throw exception
因此,此引用的值为null,对于垃圾收集器没有问题。