Consider this example,
public class NumberAsIs
{
public NumberAsIs(double number) { _number = number; }
public double Value => _number;
private double _number;
}
public class Percentage
{
public Percentage(double number) { _number = number; }
public double Value => _number * 0.01;
private double _number;
}
class Program
{
static void Main(string[] args)
{
var a = new NumberAsIs(1);
var b = new Percentage(2);
var c = a.Value b.Value; // Expect c = 1.02
}
}
Because the only purpose of NumberAsIs and Percentage is to call them for their Value method, is there a way to just call them as value types? For example,
class Program
{
static void Main(string[] args)
{
var a = new NumberAsIs(1);
var b = new Percentage(2);
double c = a b; // Expect c = 1.02
}
}
I'm not looking to redefine the operator , but to access the numeric value just by calling the object. If it's not possible just fine and say no, asking just in case there is a workaround/sugar syntax I'm not aware of.
The question is roughly related to this other: Value type class definition in C#?
CodePudding user response:
You can try implementing implicit operator
:
//TODO: better use struct, not class
public class NumberAsIs {
...
public static implicit operator double(NumberAsIs value) => value.Value;
}
//TODO: better use struct, not class
public class Percentage {
...
public static implicit operator double(Percentage value) => value.Value;
}
Now you can put
var a = new NumberAsIs(1);
var b = new Percentage(2);
// double c = 1.02 as expected
var c = a b;
// 0.98
var c2 = a - b;
// 0.02
var c3 = a * b;
CodePudding user response:
If you define both directions:
public class NumberAsIs
{
private readonly double _number;
private NumberAsIs(double d) => _number = d;
public static implicit operator double(NumberAsIs value) => value._number;
public static implicit operator NumberAsIs(double value) => new NumberAsIs(value);
}
public class Percentage
{
private readonly double _number;
private Percentage(double d) => _number = d/100.0;
public static implicit operator double(Percentage value) => value._number;
public static implicit operator Percentage(double value) => new Percentage(value);
}
It means you can do this:
NumberAsIs a = 1;
Percentage b = 2;
var c = a b; // Expect c = 1.02
Console.WriteLine(c); //prints 1.02
CodePudding user response:
I think what you want is to keep the value as defined, but convert it into a double
using whatever conversion factor applies.
Here operations such as
etc are handled by invoking the implicit conversion to double
.
public struct Number
{
public Number(double value) : this()
{
Value = value;
}
public static implicit operator double(Number number)=>number.Value;
public static implicit operator Number(double value) => new Number(value);
public double Value { get; }
public override string ToString() => $"{Value:g}";
}
public struct Percent
{
public Percent(double value) : this()
{
Value = value;
}
public static implicit operator double(Percent number) => number.Value/100;
public static implicit operator Percent(double value) => new Percent(value * 100);
public double Value { get; }
public override string ToString() => $"{Value:g}%";
}
static class Program
{
static void Main(string[] args)
{
Number a = new Number(1.0); // 1.0
Percent b = new Percent(2.0); // 2%
double c = a b;
Console.WriteLine($"{a} {b} = {c}");
// 1 2% = 1.02
}
}