正确理解静态隐式运算符

Understanding static implicit operator the right way

我有一个绝妙的想法,后来似乎没有那么绝妙,但可能我没有正确理解整个事情。

我有一个 class,可以存储一些数字。其他一些 functions/methods 需要整数,有些需要双精度。所以我想我可以创建一个隐式精度转换的 class。

public class PreciseInteger
{
    public double PreciseValue {get; private set;}
    public int RoundedValue {get; private set;}

    public PreciseInteger(double value)
    {
        PreciseValue = value;
        RoundedValue = (int)Math.Round(value, 0, MidpointRounding.AwayFromZero);
    }

    public static implicit operator PreciseInteger(int number)
    {
        return new PreciseInteger(number);
    }

    public static implicit operator PreciseInteger(double number)
    {
        return new PreciseInteger(number);
    }

    public static implicit operator int(PreciseInteger number)
    {
        return number.RoundedValue;
    }

    public static implicit operator double(PreciseInteger number)
    {
        return number.PreciseValue;
    }

    public override string ToString()
    {
        return PreciseValue.ToString();
    }
}

而使用这个class的class其实就是一个简单的属性存储class,并不多。所以现在我使用类似

的东西
double myValue = myClass.StoredValue1 / myDivider;

但是这里我只得到整数值。我不想使用显式转换(如 Convert.ToDouble(double))。那么我怎样才能确保使用的是精确值而不是四舍五入的值呢?或者我是否误解了整个概念并且根本不起作用,我将不得不使用 MyClass.MyDoubleMyClass.MyInteger 值之类的东西?

编辑:好的,如果我先说 int newInt = myClass.StoredValue1 我得到一个四舍五入的整数,如果我使用 double newDouble = myClass.StoredValue1 我得到精确的浮点数。但是没有办法说其中之一总是首选吗?

/ 运算符是为 intdouble 定义的:

double operator /(double x, double y);
int operator /(int x, int y);

当你这样做时,这两个重载都适用:

// assuming myClass.StoredValue1 and myDivider are PreciseIntegers
double myValue = myClass.StoredValue1 / myDivider;

因为您定义了到 int 的隐式转换和到 double 的隐式转换。然而,占用 ints 的 / 实际上是一个 better function member, because int is a better conversion target,因此编译器总是选择第二个重载。

解决此问题的一种方法是为 PreciseInteger:

定义您自己的 / 运算符
public static PreciseInteger operator /(PreciseInteger number1, PreciseInteger number2) {
    return number1.PreciseValue / number2.PreciseValue;
}

那么你可以这样做:

double myValue = myClass.StoredValue1 / myDivider;