【问题标题】:Operator overloading for Type类型的运算符重载
【发布时间】:2013-02-27 15:53:38
【问题描述】:

当我输入问题时,我可以看到 Operator Overloading... 问题列表。其中大多数是用于 C++ 或 Haskell 的。我的问题是针对 C# 的,可以说逻辑可能是相同的。我的问题是我想了解 C# 上下文中的运算符重载。

我在看一个教程,它显示,

DateTime dt1 = new DateTime();
//do some work
DateTime dt2 = new DateTime();
TimeSpan ts = dt2 - dt1;

作者说,在 DateTime 数据类型中使用- 是最好的运算符重载示例。我只能看到一个日期被另一个日期减去并保存到TimeSpan 对象中。它也没有使用operator关键字和static关键字。

我觉得很难理解。有人可以解释这里发生了什么吗?这是否意味着在上面的ts = dt2 - dt1 之下,有一个public static DateTime operator -(DateTime, DateTime) 正在发生?

更新:

第二个例子:

//some parameterized constructor is here to set X, Y

public static Point operator +(Point p1, Point p2)
{   
    Point p = New Point();
    p.X = p1.X + p2.X;
    p.Y = p2.Y + p2.Y;
    return p
{

在这种情况下,操作数必须与返回类型相同?

【问题讨论】:

标签: c# operator-overloading


【解决方案1】:

operator 关键字在声明重载运算符时使用,而不是在使用它时使用。

所以操作符应该是这样写的:

public static TimeSpan operator -(DateTime lhs, DateTime rhs)
{
    // Code to execute
}

当您使用该运算符时,这些都不会干扰 - 您只需在已显示的代码类型中使用它。所以这一行:

TimeSpan ts = dt2 - dt1;

将调用上面给出的代码。

示例代码:

using System;

public class Int32Wrapper
{
    private readonly int value;
    public int Value { get { return value; } }

    public Int32Wrapper(int value)
    {
        this.value = value;
    }

    public static Int32Wrapper operator +(Int32Wrapper lhs, Int32Wrapper rhs)
    {
        Console.WriteLine("In the operator");
        return new Int32Wrapper(lhs.value + rhs.value);
    }
}

class Test
{
    static void Main()
    {
        Int32Wrapper x = new Int32Wrapper(10);
        Int32Wrapper y = new Int32Wrapper(5);
        Int32Wrapper z = x + y;
        Console.WriteLine(z.Value); // 15
    }
}

回答你问题的最后一点:

这是否意味着在上面的ts = dt2 - dt1 之下,有一个public static DateTime operator -(DateTime, DateTime) 正在发生?

不-没有返回DateTime的DateTime减法运算符-只有返回TimeSpan的减法运算符。

编辑:关于Point 的第二个示例,我认为将两个Point 值加在一起在逻辑上没有意义。例如,如果您将您的家庭位置添加到您的工作位置,您会得到什么?拥有Vector 类型更有意义,然后:

public static Vector operator -(Point p1, Point p2)
public static Vector operator +(Vector v1, Vector v2)
public static Point operator +(Point p1, Vector v1)

【讨论】:

  • @aspiring:不,但谁说必须是?必须以操作数之一的类型声明运算符,仅此而已。 (或者对于转换运算符,它可以是源类型或目标类型。)
  • 必须以操作数之一的类型声明运算符,仅此而已。这确实是有价值的信息。我看到的每个示例都显示了返回类型和操作数的相同类型。我可以在这种情况下得出结论 TimeSpan 和 DateTime 相当特殊吗?我的 Point 的第二个示例遵循与 return Type 相同的 operands...
  • 我明白了。 :) 例如如果我想获得两个points 之间的距离,那么我必须将该距离返回为double 类型。 public static double operator -(Point p1, Point p2) { return Math.Sqrt(p2.X - p1.X....); }
  • @aspiring:这可行,但我不会这样做:我会返回Vector 作为两点之间更自然的差异。对于距离,您需要矢量的大小。
  • @aspiring:当您不断更新帖子以提出问题的新变体时,很难保持正确和有效的答案......
【解决方案2】:

假设您有一个“金额”类,如下所示:

public class Amount
{
    public int AmountInt { get; set; }
}

你有该类的两个实例:

Amount am1 = new Amount { AmountInt = 2 };
Amount am2 = new Amount { AmountInt = 3 };

你不能简单地这样做:

Amount am3 = am1 + am2; //compilation error

您必须向 Amount 类添加一个运算符才能提供此功能:

public static Amount operator +(Amount amount1, Amount amount2)
{
    return new Amount { AmountInt = amount1.AmountInt + amount2.AmountInt };
}

减法 (-) 也是如此。现在如果你这样做:

Amount am3 = am1 + am2;

在这种情况下,am3 的 int-value 属性将为 5。希望这会有所帮助!

【讨论】:

  • 谢谢你,又是一个可解读的例子:)
【解决方案3】:

所有的操作符都是一个方法的语法糖。例如 - 操作符可能类似于

//not the actual syntax
public MyObject minus(MyObject object1, MyObject object2)
{
    //insert custom subtraction logic here
    return result
}

您可以为您定义的任何自定义类重载运算符。

here's a tutorial I found on you actually do it

这是本教程第一个示例的相关片段

   // Declare which operator to overload (+), the types 
   // that can be added (two Complex objects), and the 
   // return type (Complex):
   public static Complex operator +(Complex c1, Complex c2) 
   {
      return new Complex(c1.real + c2.real, c1.imaginary + c2.imaginary);
   }

【讨论】:

    猜你喜欢
    • 2015-11-19
    • 1970-01-01
    • 2016-01-25
    • 2015-01-29
    • 2015-12-24
    • 1970-01-01
    • 1970-01-01
    • 2012-05-17
    • 1970-01-01
    相关资源
    最近更新 更多