更新:答えを見つけました。他に誰もいない場合は、数日以内に投稿します。
数値構造体を作成しているので、算術演算子をオーバーロードしています。4ビットの符号なし整数を表す構造体の例を次に示します。
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);
}
}
オーバーロードされた加算演算子により、次のコードが可能になります。
var x = new UInt4(10);
var y = new UInt4(11);
var z = x + y;
ここでは、計算がオーバーフローするため、変数zの値はになります5
。ただし、これも実行できるようにしたいと思います。
var x = new UInt4(10);
var y = new UInt4(11);
var z = checked ( x + y );
このサンプルはOverflowExceptionをスローする必要があります。どうすればそれを達成できますか?
チェックされたコンテキストが呼び出されたメソッドに拡張されないことはすでに確立しているため、たとえば、チェックされたコンテキストとチェックされていないコンテキストのどちらで呼び出されたかに関係なく、これはスローされません。
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);
}
加算演算子の2つのオーバーロードを宣言する方法はありますか?1つはチェックされ、もう1つはチェックされていませんか?または、実行時に呼び出し元のコンテキストを判別する方法はありますか(これは非常にありそうもないようですが、それでも質問したいと思います)、次のようになります。
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.");
}