重载基元运算符(C#)

3

有没有一种方法可以重载基本类型,例如双精度加法?我想在执行操作时自动四舍五入双精度。我的当前代码如下:

    class Test{
    public static double operator +(double x, double y){
        return Math.Round(x + y)
    }
}

但是,不幸的是出现了一个错误,提示“二进制运算符的其中一个参数必须是包含类型”。


1
你做不到。谢天谢地。 - Lucas Trzesniewski
为什么这个感激? - JPtheK9
因为它几乎没有任何好处,而且存在巨大的错误潜在风险。 - Preston Guillot
由于混乱会随之而来。 - BradleyDotNET
1
如果我创建另一个类并重载相同的运算符会发生什么?例如,如果整数的+运算符没有在任何引用的程序集中被重载,我怎么知道呢?在这种情况下,你甚至不能确定2+2=4。 - Selman Genç
显示剩余2条评论
2个回答

5
不可以,这会很糟糕。使用你的库的用户会突然获得与他们的double变量不同的行为!
但是,你可以编写和使用包装器对象。
public struct MyDouble
{
     public double Value {get; set;}

     public MyDouble(double initValue)
     {
         Value = initValue;
     }         

     public static double operator +(MyDouble x, MyDouble y){
        return Math.Round(x.Value + y.Value)
     }
}

你还可以将其转换为/从双精度浮点数进行转换,以及其他选项。这样用户就会“知道”他们正在使用你的对象,当他们的数学运算被四舍五入时,也不会感到惊讶。
如果你想从一个简单的双精度浮点数进行赋值,你需要定义一个“隐式”的操作符,类似于Nullable<T>source):
 public static implicit operator MyDouble(double value) {
            return new MyDouble(value);
        }

非常感谢!为了保持一切整洁简单,是否可以通过调用类自动调用Value?这样,我就可以轻松地执行Number = 1,而不是Number.Value = 1。 - JPtheK9
@user2994455 是的,可以使用 implicit 强制类型转换运算符。 - BradleyDotNET

4

您无法对基本类型进行重载运算符。这将在您的代码库中造成混乱。

相反,您可以创建一个简单的包装器来包装基本类型,比如说RoundedDouble

public struct RoundedDouble : IEquatable<RoundedDouble>, IComparable<RoundedDouble>
{
    public readonly double Value;

    public RoundedDouble(double value)
    {
        Value = Math.Round(value); // Or anything else
    }

    public static implicit operator RoundedDouble(double value)
    {
        return new RoundedDouble(value);
    }

    public static implicit operator double(RoundedDouble wrapper)
    {
        return wrapper.Value;
    }

    public int GetHashCode()
    {
        return Value.GetHashCode();
    }

    public bool Equals(object other)
    {
        if (other is RoundedDouble)
            return ((RoundedDouble)other).Value == Value;

        return false;
    }

    public string ToString()
    {
        return Value.ToString();
    }

    // Add your operators here, and implement the interfaces
}

这是一个结构体,它具有与double相同的值语义。

通过添加运算符并实现IEquatable<RoundedDouble>IComparable<RoundedDouble>,可以扩展它。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接