In my code I have variables of type System.Double that either represent a quantity or a quantityDifference. In order to make my code safer, I would like to pass in a value of either type Quantity or QuantityDelta rather than double (to avoid passing in the the wrong value).
I can create a struct or class with a Value property or field but then I have to allocate memory for it and use the .Value syntax to use it:
public class Quantity
{
public Quantity(double value) { Value = value; }
public double Value;
}
and
var difference = new Quantity(differenceValue);
var used = difference.Value;
Is there a way to create a custom value type for this purpose, so the code reads like
Quantity difference = differenceValue;
var used = difference
CodePudding user response:
Use the implicit operator.
public struct Quantity
{
private readonly double value;
public Quantity(double value) { this.value = value; }
public double Value => value;
public static implicit operator double(Quantity value) => value.value;
public static implicit operator Quantity(double value) => new Quantity(value);
}
Also, since you are simply wrapping a value type, it would be best to use a struct
rather than a class
.
CodePudding user response:
Operator overloading will help with Quantity difference = differenceValue;
, specifically an implicit conversion operator for converting a double value into a Quantity struct instance.
However, nothing will help you with convincing the compiler to choose the double type for the var-declared used variable in var used = difference
. Because var
instructs the compiler to use the type of the right-hand expression as the type for the var-declared variable used. Which is Quantity here. I.e., the compiler will understand var used = difference
as Quantity used = difference
.
CodePudding user response:
This is a quick sample I created for a Quantity
struct that has basic operations of Addition, Subtraction, Multiplication, and Division.
public readonly struct Quantity
{
private readonly double num;
public Quantity(double number)
{
num = number;
}
public static Quantity operator (Quantity a, Quantity b) => new Quantity(a.num b.num);
public static Quantity operator -(Quantity a, Quantity b) => new Quantity(a.num - b.num);
public static Quantity operator *(Quantity a, Quantity b) => new Quantity(a.num * b.num);
public static Quantity operator /(Quantity a, Quantity b)
{
if (b.num == 0)
{
throw new DivideByZeroException();
}
return new Quantity(a.num / b.num);
}
public override string ToString() => $"{num}";
}
A few quick test cases
var a = new Quantity(5);
var b = new Quantity(2);
Debug.WriteLine(a b); // output: 7
Debug.WriteLine(a - b); // output: 3
Debug.WriteLine(a * b); // output: 10
Debug.WriteLine(a / b); // output: 2.5
If you do want the difference returned in a type called QuantityDelta
you could replace the -
operator above with:
public static QuantityDelta operator -(Quantity a, Quantity b) => new QuantityDelta(a.num - b.num);
And, add a new QuantityDelta
struct as per:
public readonly struct QuantityDelta
{
private readonly double num;
public QuantityDelta(double number)
{
num = number;
}
public override string ToString() => $"{num}";
}