Is there a way I can overload primitives, for example addition with doubles? I want to automatically round the doubles whenever an operation is performed. My current code is this:
class Test{
public static double operator +(double x, double y){
return Math.Round(x + y)
}
}
but there's an unfortunate error that says "One of the parameters of a binary operator must be the containing type".
You can't overload operators on primitive types. This would cause havoc in your codebase.
What you can do instead, is to create a simple wrapper around the primitive type, let's say RoundedDouble
:
public struct RoundedDouble : IEquatable<RoundedDouble>, IComparable<RoundedDouble>
{
public readonly double Value;
public RoundedDouble(double value)
{
Value = Math.Round(value); // Or anything else
}
public static implicit operator RoundedDouble(double value)
{
return new RoundedDouble(value);
}
public static implicit operator double(RoundedDouble wrapper)
{
return wrapper.Value;
}
public int GetHashCode()
{
return Value.GetHashCode();
}
public bool Equals(object other)
{
if (other is RoundedDouble)
return ((RoundedDouble)other).Value == Value;
return false;
}
public string ToString()
{
return Value.ToString();
}
// Add your operators here, and implement the interfaces
}
This is a structure. It has the same value semantics as a double
.
Extend it by adding the operators, and by implementing at least IEquatable<RoundedDouble>
and IComparable<RoundedDouble>
.
No, and this would be horrible. Users using your library would suddenly get different behaviors from their double
variables!
You can write and use a wrapper object however:
public struct MyDouble
{
public double Value {get; set;}
public MyDouble(double initValue)
{
Value = initValue;
}
public static double operator +(MyDouble x, MyDouble y){
return Math.Round(x.Value + y.Value)
}
}
You can also make it castable to/from a double, among other options. This way users know they are using your object and won't be surprised when their math operations are rounded.
If you want to assign from a simple double, you would need to define an implicit operator, similar to that of Nullable<T>
(source):
public static implicit operator MyDouble(double value) {
return new MyDouble(value);
}