Disclaimer I typed all this and then I thought: “Should I even publish this? I mean, this is a pretty bad idea, and therefore it doesn’t really help the OP ... In the end, I realized that I already typed all this ; I could also go ahead and click “Post your answer.” Although this is a “bad” idea, it seems to be interesting (for me, anyway). So maybe some strange way will come in handy by reading it.
For some reason, I have a suspicion that the above disclaimer is not going to protect me from downvotes, though ...
Here is a completely crazy idea.
In fact, I would not recommend putting it in any production environment at all , because I literally thought about it just now, which means that I really did not think about it completely, and I'm sure that about a billion problems. This is just an idea.
But the basic concept is to create a type that can be used for arithmetic expressions that internally use double for each term in the expression, only to be evaluated as the desired type (in this case: int ) at the end.
You will start with a type like:
// Probably you'd make this implement IEquatable<Term>, IEquatable<double>, etc. // Probably you'd also give it a more descriptive, less ambiguous name. // Probably you also just flat-out wouldn't use it at all. struct Term { readonly double _value; internal Term(double value) { _value = value; } public override bool Equals(object obj) { // You would want to override this, of course... } public override int GetHashCode() { // ...as well as this... return _value.GetHashCode(); } public override string ToString() { // ...as well as this. return _value.ToString(); } }
Then you define the implicit conversions to / from double and the types (s) you want to support (again: int ). Like this:
public static implicit operator Term(int x) { return new Term((double)x); } public static implicit operator int(Term x) { return (int)x._value; }
Then define the operations themselves: Plus , Minus , etc. For your example code, we need Times (for * ) and DividedBy (for / ):
public Term Times(Term multiplier) {
Finally, write a helper class static , so that you can perform operations with Term on all types that you want to work with (perhaps only int for starters):
public static class TermHelper { public static Term Times(this int number, Term multiplier) { return ((Term)number).Times(multiplier); } public static Term DividedBy(this int number, Term divisor) { return ((Term)number).DividedBy(divisor); } }
What would you buy all this? Almost nothing! But it will clear your expressions, hide all these unsightly explicit casts, making your code much more attractive and much more impossible to debug. (Once again, this is not an endorsement , just a crazy idea).
So instead:
int d = (int)(a * (b / (double)c));
You will have the following:
int d = a.Times(b.DividedBy(c));
Is it worth it?
Well, if writing casting operations were the worst in the world, for example, even worse than relying on code that is too smart for its own good, then perhaps such a solution would be appropriate.
Since the above is clearly not true ... the answer is quite expressive NO . But I just thought that I would share this idea anyway to show that such a thing is (possibly) possible.