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

时间:2010-06-25 21:46:05

标签: 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];
   }

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

尝试使用here技术时出现编译错误。

我认为如果运算符不是静态的,我将能够正常工作,因为我可以覆盖基类的运算符。这可能吗?

一旦我知道如何比较基本属性(我认为演员与任务类型[(任务)t1 ==(任务)t2]不起作用)?

5 个答案:

答案 0 :(得分:9)

你做不到。运算符未被重写,它们重载。这意味着要使用的实现完全在编译时决定。

可以做的一件事是覆盖Equals中的Task并从==调用它,然后再次覆盖 TaskA。这也使“基本属性”检查变得简单 - 只需从base.Equals调用TaskA.Equals

答案 1 :(得分:7)

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

在仅支持单个虚拟调度的语言中实现双调度的标准方法是访问者模式。你可以考虑一下。

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

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

答案 2 :(得分:2)

该帖子是关于C ++的。 将运算符视为静态函数。你不能超载它。

但是,您可以声明实例虚方法,并在您的运算符中调用它。但是note运算符接受两个参数,它们可能有不同的实际类型,所以你需要决定如何从这两个参数中选择一个参数。

public class Task
{
     public virtual bool MyMethod(Task anotherTask) { return true; }

     public static bool operator==(Task t1, Task t2) 
     {
          return t1 == null ? false : t1.MyMethod(t2);
     } 
}

public class TaskA
{
      public override bool MyMethod(Task anotherTask) { return false; }
}

答案 3 :(得分:1)

如果你可以使Task成为一个抽象类,那么模板方法模式可能是一个很好的方法。

public abstract class Task
{
    string Name;
    protected abstract bool DoEquals( Task rhs );

    public static bool operator ==(Task t1, Task t2)
    {
        return t1.DoEquals( t2 );
    }
}

public class TaskA : Task
{
    protected bool DoEquals( Task rhs )
    {
        return /* custom compare */
    }
}

public class TaskB : Task
{
    protected bool DoEquals( Task rhs )
    {
        return /* custom compare */
    }
}

答案 4 :(得分: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;
  }
}