开发者

How can i override a base class's == operator, so the override gets called

With code like the following

public class Task
{
  string Name;
  public static bool operator ==(Task t1, Task t2)
  { return t1.Name = t2.Name && t1.Ge开发者_JAVA技巧tType() == 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];
   }

I'm trying to make sure that the derived operator (TaskA.==) is called.

I get compilation error when trying the technique here.

I think i'd be able to get it to work correctly if the operator was not static, because i could then override the base class's operator. Is that possible?

Once i get that how would i compare the base properties (i would think the cast to task type [(Task)t1 == (Task)t2] would not work)?


You can't. Operators aren't overridden, they're overloaded. That means the implementation to be used is entirely decided at compile-time.

One thing you can do is override Equals in Task and call it from ==, and then override it again in TaskA. That also makes the "base properties" check easy - just call base.Equals from TaskA.Equals.


What you're trying to do is really quite difficult in C#. Basically what you want is an operator whose behaviour is determined at runtime based on the runtime types of both arguments. That is hard; the == operator is dispatched based on the compile time types of both operands, and the .Equals method is dispatched based on the runtime type of the receiver but the compile time type of the argument.

The standard way of implementing double dispatch in a language that supports only single virtual dispatch is the Visitor Pattern. You might look into that.

For further reading on this subject you might check out my article here:

Link


That post was about C++. Consider operator as static function. You can't overload it.

But, you can declare instance virtual method, and call it inside your operator. But note operator accepts two arguments, and they may have different actual type, so you need to deside how to prefer one argument from these two.

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; }
}


If you can make Task an abstract class the template method pattern might be a good one to follow.

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 */
    }
}


My hybrid solution that seems to work.

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;
  }
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜