Main Site Documentation

Try-Catch in constructor NETMF


#1

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?
        }
    }
}

#2

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.


#3

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.


#4

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.


#5

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
    }
}