Basic Idea
Assuming you want a behavior such as this:
List<CheckedInt> myIntList = new List<CheckedInt>();
CheckedInt check1 = int.MaxValue;
CheckedInt check2 = 1;
myIntList.Add(check1 + check2); //exception occurs!
One of the cleanest way to do that (such that the operation code such as x + y can be retained but capable of throwing exception at the same time) would be to define your own CheckedInt (based on int) with overloaded operators.
Implementation
The struct
The CheckedInt struct would be something like this:
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;
}
}
The Exception
And you may define your own exception too.
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
}
And now, you have a real List of CheckedInt with you.
The Use
Simply use it like this:
CheckedInt check1 = int.MaxValue;
CheckedInt check2 = 1;
And this statement:
List<CheckedInt> myIntList = new List<CheckedInt>();
myIntList.Add(check1 + check2); //exception!
Will throw an exception MyCheckedIntException for you.
The Expansion, for Cleaner Look
If you want to use it like any of these:
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
Then simply add overloading to the 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
}
You can do likewise for all other operators.