Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Throwing exceptions from a constructor in .NET

Are there any memory leaks when I throw an exception from a constructor like the following?

class Victim
{
    public string var1 = "asldslkjdlsakjdlksajdlksadlksajdlj";

    public Victim()
    {
        //throw new Exception("oops!");
    }
}

Will the failing objects be collected by the garbage collector?

like image 878
Mik Kardash Avatar asked May 29 '09 14:05

Mik Kardash


People also ask

Can I throw exception from constructor C#?

Throwing exceptions in constructors in C# is fine, but a constructor should always create a valid object.

Can you throw an exception in a constructor?

The short answer to the question “can a constructor throw an exception in Java” is yes! Of course, properly implementing exceptions in your constructors is essential to getting the best results and optimizing your code.

What happens when constructor throws exception?

Throwing an exception in a constructor can lead to partially initialized objects. As described in Guideline 7.3 of Java Secure Coding Guidelines, partially initialized objects of a non-final class are prone to a security concern known as a Finalizer Attack.

What happens if a static constructor throws an exception in C#?

If a static constructor throws an exception, the runtime doesn't invoke it a second time, and the type will remain uninitialized for the lifetime of the application domain.


2 Answers

In general this is safe from the perspective of not leaking memory. But throwing exceptions from a constructor is dangerous if you allocate unmanaged resources in the type. Take the following example

public class Foo : IDisposable { 
  private IntPtr m_ptr;
  public Foo() {
    m_ptr = Marshal.AllocHGlobal(42);
    throw new Exception();
  }
  // Most of Idisposable implementation ommitted for brevity
  public void Dispose() {
    Marshal.FreeHGlobal(m_ptr);
  }
}

This class will leak memory every time you try to create even if you use a using block. For instance, this leaks memory.

using ( var f = new Foo() ) {
  // Won't execute and Foo.Dispose is not called
} 
like image 159
JaredPar Avatar answered Sep 23 '22 20:09

JaredPar


Throwing exceptions from a constructor should be fine if you have created no unmanaged resources. However, if you do create unmanaged resources in the constructor, the whole body of that constructor, including throws, should be wrapped in a try/catch. To steal JaredPar's great example:

public class Foo : IDisposable { 
  private IntPtr m_ptr;
  public Foo() {
    try
    {
        m_ptr = Marshal.AllocHGlobal(42);
        throw new Exception();
    }
    catch
    {
        Dispose();
        throw;
    }
  }
  // Most of Idisposable implementation ommitted for brevity
  public void Dispose() {
    Marshal.FreeHGlobal(m_ptr);
  }
}

The following would now work:

using ( var f = new Foo() ) {
  // Won't execute, but Foo still cleans itself up
}
like image 26
jrista Avatar answered Sep 19 '22 20:09

jrista