正确理解静态隐式运算符
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.MyDouble
和 MyClass.MyInteger
值之类的东西?
编辑:好的,如果我先说 int newInt = myClass.StoredValue1
我得到一个四舍五入的整数,如果我使用 double newDouble = myClass.StoredValue1
我得到精确的浮点数。但是没有办法说其中之一总是首选吗?
/
运算符是为 int
和 double
定义的:
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
的隐式转换。然而,占用 int
s 的 /
实际上是一个 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;
我有一个绝妙的想法,后来似乎没有那么绝妙,但可能我没有正确理解整个事情。
我有一个 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.MyDouble
和 MyClass.MyInteger
值之类的东西?
编辑:好的,如果我先说 int newInt = myClass.StoredValue1
我得到一个四舍五入的整数,如果我使用 double newDouble = myClass.StoredValue1
我得到精确的浮点数。但是没有办法说其中之一总是首选吗?
/
运算符是为 int
和 double
定义的:
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
的隐式转换。然而,占用 int
s 的 /
实际上是一个 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;