C#重载operator ==和!= [英] C# Overloading Operator == and !=

查看:199
本文介绍了C#重载operator ==和!=的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在这些几个类和界面中遇到问题。

I am having problems getting the desired behavior out of these few classes and interfaces.

这是我的问题,

//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);

上面的assert是失败的,因为它似乎是去对象类的equals方法,而不是重载

The assert above is failing because it seems to be going to the object class's equals method instead of the overloaded operator in the Node and NodeId classes.

如果您对如何获得所需的行为有任何建议,那将是非常棒的。

If you have any suggestions on how I can get the desired behavior, that would be awesome.

这是我正在工作的框架的一部分:

Here is part of the Framework I am working on:

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;

}


推荐答案

在编译时基于操作数的声明类型解析,而不是在运行时对象的实际类型。另一种说法是,操作符重载不是虚拟的。所以你在上面做的比较是 INode.operator == ,而不是 Node.operator == 。由于 INode.operator == 未定义,重载解析为 Object.operator == ,这只是参考比较。

Operator overloads are resolved at compile time based on the declared types of the operands, not on the actual type of the objects at runtime. An alternate way of saying this is that operator overloads aren't virtual. So the comparison that you're doing above is INode.operator==, not Node.operator==. Since INode.operator== isn't defined, the overload resolves to Object.operator==, which just does reference comparison.

没有真正好的方法。最正确的做法是使用 Equals(),而不是 == 任何地方的操作数可能是对象。如果真的,真的需要一个假的虚拟运算符重载,你应该在你的对象继承的根基类中定义 operator == ,并且重载调用等于。但请注意,这将不适用于接口,这是你有的。

There is no really good way around this. The most correct thing to do is to use Equals() rather than == anywhere the operands might be objects. If you really, really need a fake virtual operator overload, you should define operator == in the root base class that your objects inherit from, and have that overload call Equals. Note, however, that this won't work for interfaces, which is what you have.

这篇关于C#重载operator ==和!=的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆