【问题标题】:Overloading Primitive Operator (C#)重载原始运算符 (C#)
【发布时间】:2015-02-11 00:13:02
【问题描述】:

有没有一种方法可以重载基元,例如双精度加法?每当执行操作时,我想自动舍入双打。我目前的代码是这样的:

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

但是有一个不幸的错误说“二元运算符的参数之一必须是包含类型”。

【问题讨论】:

  • 你不能。谢天谢地。
  • 为什么要感恩?
  • 因为它几乎没有任何好处,而且有很大的潜在错误。
  • 因为会发生混乱
  • 如果我创建另一个类并重载同一个运算符会发生什么?例如,我怎么知道整数的 + 运算符是否没有重载任何引用的程序集?在那种情况下,你甚至不能确定 2+2=4

标签: c# double operator-overloading


【解决方案1】:

不,这将是可怕的。使用您的库的用户会突然从他们的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)
     }
}

除其他选项外,您还可以将其转换为可转换为/从双重转换。这样用户知道他们正在使用您的对象,并且在他们的数学运算被四舍五入时不会感到惊讶。

如果你想从一个简单的 double 中赋值,你需要定义一个 implicit 运算符,类似于 Nullable<T> (source):

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

【讨论】:

  • 非常感谢!为了保持一切整洁和简单,是否可以通过调用类来自动调用 Value ?这样,我可以轻松地做到 Number = 1 而不是 Number.Value = 1。
  • @user2994455 是的,使用 implicit 转换运算符。
【解决方案2】:

您不能对原始类型重载运算符。这会对您的代码库造成严重破坏。

您可以做的是围绕原始类型创建一个简单的包装器,比如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&lt;RoundedDouble&gt;IComparable&lt;RoundedDouble&gt;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-07-21
    • 1970-01-01
    • 1970-01-01
    • 2016-02-19
    • 1970-01-01
    • 2016-04-08
    • 2012-06-02
    相关资源
    最近更新 更多