代码之家  ›  专栏  ›  技术社区  ›  Meiscooldude

C#重载运算符==和=

  •  3
  • Meiscooldude  · 技术社区  · 14 年前

    我很难从这几个类和接口中获得所需的行为。

    这是我的问题,

    //Inside a Unit Test that has access to internal methods and properties
    
    INode  firstNode, secondNode;
    
    INodeId  id = new NodeId (4);
    
    first = new Node (id, "node");
    second = new Node (id, "node");
    
    Assert.IsTrue (first == second);
    

    上面的断言失败了,因为它似乎要转到对象类的equals方法,而不是Node和NodeId类中的重载运算符。

    如果你对我如何获得想要的行为有任何建议,那就太棒了。

    public interface IIdentifier<T> where T : class
    {
        TKeyDataType GetKey<TKeyDataType> ();
    
        bool Equals (IIdentifier<T> obj;
    }
    
    public interface INode
    {
        string name
        {
            get;
        }
    
        INodeId id
        {
            get;
        }
    }
    
    public interface INodeId : IIdentifier<INode>
    {
    }
    
    public class Node : INode
    {
        internal Node(INodeId  id, string name)
        { 
           //Work
        }
    
        public static bool operator == (Node n1, Node n2)
        {
            return n1.equals(n2);
        }
    
        public static bool operator != (Node n1, Node n2)
        {
            return !n1.equals(n2);
        }
    
        public bool Equals (INode  node)
        {
            return this.name == node.name &&
                   this.id = node.id;
        }
    
        #region INode Properties
    
        }
    
    public class NodeId : INodeId
    {
    
        internal NodeId(int id)
        { 
           //Work
        }
    
        public static bool operator == (NodeId  n1, NodeId  n2)
        {
            return n1.equals(n2);
        }
    
        public static bool operator != (NodeId  n1, NodeId  n2)
        {
            return !n1.equals(n2);
        }
    
        public override bool Equals (object obj)
        {
            return this.Equals ((IIdentifier<INode>) obj);
        }
    
        public bool Equals (IIdentifier<INode> obj)
        {
            return obj.GetKey<int>() ==  this.GetKey<int>();
        }
    
        public TKeyDataType GetKey<TKeyDataType> ()
        {
            return (TKeyDataType) Convert.ChangeType (
                m_id,
                typeof (TKeyDataType),
                CultureInfo.InvariantCulture);
        }
    
    
        private int m_id;
    
    }
    
    3 回复  |  直到 14 年前
        1
  •  6
  •   JSBÕ±Õ¸Õ£Õ¹    14 年前

    运算符重载在编译时根据声明的操作数类型而不是运行时对象的实际类型进行解析。另一种说法是操作符重载不是虚拟的。所以你在上面做的比较是 INode.operator== Node.operator== . 自从 INode运算符== Object.operator== ,它只进行引用比较。

    没有什么好办法可以解决这个问题。最正确的做法是使用 Equals() 而不是 == 操作数可能是对象的任何位置。如果你真的,真的需要一个假的虚拟操作符重载,你应该定义 operator == 在对象继承自的根基类中,并具有重载调用 Equals . 但是,请注意,这对接口不起作用,这正是您所拥有的。

        2
  •  1
  •   Mark Synowiec    14 年前

    public override bool Equals (object obj)
    {
        if (obj is Node)
        {
            return this.Equals(obj as Node);
        }
        return false;
    }
    
    // your code (modified to take a Node instead of an INode)
    public bool Equals (Node  node)
    {
        return this.name == node.name &&
               this.id = node.id;
    }
    
        3
  •  0
  •   Jeff Hornby    14 年前

    它使用==from对象,因为firstNode和secondNode不是Node类型,而是INode类型。编译器无法识别底层类型。

    因为不能在接口中重载运算符,所以最好重写代码,使其不使用INode接口。