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.");
}