簡體   English   中英

是否可以使用 class 實例作為 C# 中的值?

[英]Is it possible to use a class instance as a value in C#?

考慮這個例子,

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
    }
}

因為 NumberAsIs 和 Percentage 的唯一目的是為其 Value 方法調用它們,有沒有辦法將它們稱為值類型? 例如,

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
    }
}

我不是要重新定義 operator+,而是要通過調用 object 來訪問數值。 如果不可能,就說不,以防萬一有我不知道的解決方法/糖語法。

這個問題大致與此有關: C# 中的值類型 class 定義?

您可以嘗試實現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;
}

現在你可以放

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;

如果定義兩個方向:

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);
}

這意味着你可以這樣做:

NumberAsIs a = 1;
Percentage b = 2;
var c = a + b; // Expect c = 1.02
Console.WriteLine(c); //prints 1.02

我認為您想要的是保持定義的值,但使用任何適用的轉換因子將其轉換為double精度值。

在這里,諸如+之類的操作是通過調用隱式轉換為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
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM