Overloading the + operator so it is sensitive to being called in a checked or unchecked context

StackOverflow https://stackoverflow.com/questions/15443841

Domanda

UPDATE: I've found the answer, which I will post in a couple of days if nobody else does.


I am creating a numeric struct, so I am overloading the arithmetical operators. Here is an example for a struct that represents a 4-bit unsigned integer:

public struct UInt4
{
    private readonly byte _value;

    private const byte MinValue = 0;
    private const byte MaxValue = 15;

    public UInt4(int value)
    {
        if (value < MinValue || value > MaxValue)
            throw new ArgumentOutOfRangeException("value");

        _value = (byte) value;
    }

    public static UInt4 operator +(UInt4 a, UInt4 b)
    {
        return new UInt4((a._value + b._value) & MaxValue);
    }
}

The overloaded addition operator allows this code:

var x = new UInt4(10);
var y = new UInt4(11);
var z = x + y;

Here, the calculation overflows, so the variable z has the value 5. I would also like to be able to do this, however:

var x = new UInt4(10);
var y = new UInt4(11);
var z = checked ( x + y );

This sample should throw an OverflowException. How can I achieve that?

I have already established that the checked context does not extend to called methods, so, for example, this does not throw, regardless of whether it is called in a checked or unchecked context:

public static UInt4 operator +(UInt4 a, UInt4 b)
{
    int i = int.MaxValue;

    //this should throw in a checked context, but when
    //the operator is used in a checked context, this statement
    //is nonetheless unchecked.
    byte b = (byte)i;

    return new UInt4((a._value + b._value) & MaxValue);
}

Is there a way of declaring two overloads of the addition operator, one checked and the other unchecked? Alternatively, is there a way to determine at run time the context of the caller (which seems highly unlikely, but I thought I'd ask nonetheless), something like this:

public static UInt4 operator +(UInt4 a, UInt4 b)
{
    byte result = (byte)(a._value + b._value);

    if (result > MaxValue)
        if (ContextIsChecked())
            throw new OverflowException();
        else
            result &= MaxValue;
     return new UInt4(result);
}

private static bool ContextIsChecked()
{
    throw new NotImplementedException("Please help.");
}
È stato utile?

Soluzione

According to MSDN, the checked and unchecked keywords only apply to the integral types. Therfore, you cannot create your own types that can make use of the checked and unchecked keywords.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top