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.