如何覆盖基类的==运算符,以便调用override

red*_*der 6 c# operator-overloading equals-operator

使用以下代码

public class Task
{
  string Name;
  public static bool operator ==(Task t1, Task t2)
  { return t1.Name = t2.Name && t1.GetType() == t2.GetType(); }
}
public class TaskA : Task
{
   int aThing;
   public static bool operator ==(TaskA t1, TaskA t2)
   { 
      return (Task)t1 == (Task)t2 && t1.GetType() == t2.GetType()
          && t1.aThing == t2.aThing; }
}
public class TaskB : Task  //more of the same

class Stuffin
{
   List<Task> Tasks;

   void CheckIt()
   {
      bool theSame = Tasks[0] == Tasks[1];
   }
Run Code Online (Sandbox Code Playgroud)

我正在尝试确保调用派生运算符(TaskA.==).

这里尝试这种技术时出现编译错误.

如果运算符不是静态的,我想我能够使它正常工作,因为我可以覆盖基类的运算符.那可能吗?

一旦我得到了如何比较基本属性(我认为演员与任务类型[(任务)t1 ==(任务)t2]将无法工作)?

Jon*_*eet 10

你不能.操作符不会被覆盖,它们会被重载.这意味着要使用的实现完全在编译时决定.

有一两件事你可以做的是覆盖EqualsTask从调用它==,然后覆盖它再次TaskA.这也使得"基本属性"检查变得容易 - 只需base.Equals从中调用TaskA.Equals.


Eri*_*ert 7

你想要做的事情在C#中真的很难.基本上你想要的是一个运算符,它的行为是在运行时根据两个参数的运行时类型确定的.那很难; ==运算是基于所调度的编译时间类型两个操作数,并且所述方法.Equals基于所述调度运行时类型的接收器,但编译时所述的类型的参数.

在支持单个虚拟调度的语言中实现双调度的标准方法是访问者模式.你可能会调查一下.

有关此主题的进一步阅读,您可以在此处查看我的文章:

http://blogs.msdn.com/b/ericlippert/archive/2009/04/09/double-your-dispatch-double-your-fun.aspx


red*_*der 0

我的混合解决方案似乎有效。

public class Task
{
  string Name;
  public static bool operator ==(Task t1, Task t2)
  { 
    if ((object)t1 == null || (object)t2 == null)
    {
      return (object)t1 == null && (object)t2 == null;
    }

    return t1.Name == t2.Name && t1.GetType() == t2.GetType(); }
  public virtual bool Equals(Task t2)
  {
     return this == t2;
  }
}

public class TaskA : Task
{
  int aThing;
  public static bool operator ==(TaskA t1, TaskA t2)
  { 
    if ((object)t1 == null || (object)t2 == null)
    {
      return (object)t1 == null && (object)t2 == null;
    }

    return (Task)t1 == (Task)t2 && t1.aThing == t2.aThing;
  }
  public override bool Equals(Task t2)
  {
    return this == t2 as TaskA;
  }
}
Run Code Online (Sandbox Code Playgroud)