Try-Catch in constructor NETMF

NetMF 4.3. G30 SoC

Is it okay to have a try-catch in an object’s constructor?

MyObject InstanceOfMyObject = new MyObject(9999); // the caller

class MyObject
{
    private byte[] A;

    public MyObject(ushort Size)
    {
        try
        {
            A = new byte[Size]; // might throw an error
        }
        catch
        {
            // what do I do here? 
            // How do I delete this non-initialized object?
            // What will be returned to the caller?
        }
    }
}

If you can’t recover in the catch area, then you should re-throw the exception.

You could also have a success flag that says object was properly created.

Use a factory method and move the try/catch there.

class Foo {
    public void Bar() {
        var bla = MyObject.TryCreate(9999);
        // now need to handle the case where 'bla' is null!
    }
}

class MyObject {
    public static MyObject TryCreate(ushort size) {
        MyObject obj;
        try {
            // it is a good practice to keep content of try clause as narrow
            // as possible to not accidentially catch more than what's intended
            obj = new MyObject(size);
        } catch (OutOfMemoryException) { // only catch specific types of exceptions
            // not enough memory
            return null;
        }
        return obj;
    }
    
    private byte[] _array;

    // private constructor ensures that only TryCreate can be used to create a MyObject
    private MyObject(ushort size) {
        _array = new byte[size]; // might throw an error
    }
}

Hope this helps.

Thanks @Banjobeni and @Mike

I had heard of a factory before but never thought I needed one until now. This did the trick.

And checking if the returned reference is null does the job of the “success flag” well.

How do you feel about this all being inside the class itself?

Here is the beginning of a new class I am creating:

class CriticalTransactionTimer
{
    public static delegate void Callback();

    public uint Timeout_s { get; private set; }
    public uint NumberOfRetries { get; private set; }

    private Callback ElapsedCallback;
    private Callback FailureCallback;

    public static CriticalTransactionTimer TryCreateTimer(uint timeout_s, uint numberOfTries, Callback OnTimerElapsed, Callback OnFailure)
    {
        CriticalTransactionTimer returnVal;
        try
        {
            returnVal = new CriticalTransactionTimer(timeout_s, numberOfTries, OnTimerElapsed, OnFailure);
        }
        catch ( OutOfMemoryException )
        {
            returnVal = null;
            if(OnFailure != null)
                OnFailure();
        }

        return returnVal;
    }

    private CriticalTransactionTimer(uint _timeout_s, uint _numberOfTries, Callback _OnTimerElapsed, Callback _OnFailure)
    {
        // actual construction
    }
}