基本思路
假设您想要这样的行为:
List<CheckedInt> myIntList = new List<CheckedInt>();
CheckedInt check1 = int.MaxValue;
CheckedInt check2 = 1;
myIntList.Add(check1 + check2); //exception occurs!
其中一种最干净的方法(这样可以保留x + y之类的操作代码,但同时可以使用throwing exception)是定义您自己的CheckedInt(基于int)和重载的运算符。
实施
结构
CheckedInt struct 是这样的:
public struct CheckedInt {
private int Value { get; set; }
public CheckedInt(int value)
: this() {
Value = value;
}
public static implicit operator CheckedInt(int me) {
return new CheckedInt(me);
}
public static CheckedInt operator +(CheckedInt lhs, CheckedInt rhs) {
double testResult = (double)lhs.Value + (double)rhs.Value;
if (testResult > int.MaxValue || testResult < int.MinValue)
throw new MyCheckedIntException();
return new CheckedInt(lhs.Value + rhs.Value); //note that direct lhs+rhs will cause StackOverflow
}
public static CheckedInt operator -(CheckedInt lhs, CheckedInt rhs) {
double testResult = (double)lhs.Value - (double)rhs.Value;
if (testResult > int.MaxValue || testResult < int.MinValue)
throw new MyCheckedIntException();
return new CheckedInt(lhs.Value - rhs.Value); //note that direct lhs-rhs will cause StackOverflow
}
public static CheckedInt operator *(CheckedInt lhs, CheckedInt rhs) {
double testResult = (double)lhs.Value * (double)rhs.Value;
if (testResult > int.MaxValue || testResult < int.MinValue)
throw new MyCheckedIntException();
return new CheckedInt(lhs.Value * rhs.Value); //note that direct lhs*rhs will cause StackOverflow
}
public static CheckedInt operator /(CheckedInt lhs, CheckedInt rhs) {
double testResult = (double)lhs.Value / (double)rhs.Value;
if (testResult > int.MaxValue || testResult < int.MinValue)
throw new MyCheckedIntException();
return new CheckedInt(lhs.Value / rhs.Value); //note that direct lhs-rhs will cause StackOverflow
}
//Add any other overload that you want
public override string ToString() { //example
return Value.ToString();
}
public bool Equals(CheckedInt otherInt) { //example
return Value == otherInt.Value;
}
}
例外
您也可以定义自己的异常。
public class MyCheckedIntException : Exception {
public MyCheckedIntException() {
//put something
}
public MyCheckedIntException(string message) : base(message) {
//put something
}
public MyCheckedIntException(string message, Exception inner) : base(message, inner) {
//put something
}
现在,您拥有真正的List 和CheckedInt。
用途
像这样简单地使用它:
CheckedInt check1 = int.MaxValue;
CheckedInt check2 = 1;
还有这句话:
List<CheckedInt> myIntList = new List<CheckedInt>();
myIntList.Add(check1 + check2); //exception!
将为您抛出异常MyCheckedIntException。
扩展,让外观更简洁
如果你想像下面这样使用它:
myIntList.Add(check1 + 1); //note that `1` is not type of checked integer
myIntList.Add(1 + check1); //note that `1` is not type of checked integer
然后只需将overloading 添加到operator overloads:
public static CheckedInt operator +(CheckedInt lhs, int rhs) { //note the type of rhs
double testResult = (double)lhs.Value + (double)rhs;
if (testResult > int.MaxValue || testResult < int.MinValue)
throw new MyCheckedIntException();
return new CheckedInt(lhs.Value + rhs); //note that direct lhs+rhs will cause StackOverflow
}
public static CheckedInt operator +(int lhs, CheckedInt rhs) { //not the type of lhs
double testResult = (double)lhs + (double)rhs.Value;
if (testResult > int.MaxValue || testResult < int.MinValue)
throw new MyCheckedIntException();
return new CheckedInt(lhs + rhs.Value); //note that direct lhs+rhs will cause StackOverflow
}
您可以对所有其他运算符执行同样的操作。