Why does ((object)(int)1).Equals(((object)(ushort)1)) yield false?

时光总嘲笑我的痴心妄想 提交于 2019-12-08 15:07:19

问题


I have the Situation that I have an object which I want to check for equality with another object.

public static bool Equals(object a, object b)
{
    return a.Equals(b);
}

A Problem occurs when a = 1 (integer) and b = 1 (ushort (or basically not integer)). I wondered whether this shouldn't yield true, but it does return false...

Edit

What makes it even worse is this:

Hashtable ht = new Hashtable();
ht.Add((int)1, "SOME STRING");
ht.Add((short)1, "SOME STRING");
ht.Add((long)1, "SOME STRING");

I think that the value '1' should only be allowed once.


回答1:


Int32.Equals(object) returns true only if the other object is also an instance of Int32:

true if obj is an instance of Int32 and equals the value of this instance; otherwise, false.

In code (ILSpy, .NET 4):

public override bool Equals(object obj)
{
    return obj is int && this == (int)obj;
}

Since obj is int returns false you get a false.

Edit: ragarding to your edit(Hashtable with "similar" keys): if you don't want to allow duplicate objects use a Dictionary<int, string> instead(preferred) or add only ints to the HashTable.




回答2:


Here's a simple class and implementation of equality comparers. As you can see, the standard apporach for equals is to make sure they are of the same time first, and then, that the inside matches (in our case, a string and a date).

If you want something else, you can always override it to your heart content, and cast both sides to something you're happy with :)

public struct InputEntry
{
    public DateTime Date { get; set; }
    public string Entry { get; set; }

    public bool Equals(InputEntry other)
    {
        return Date.Equals(other.Date) && string.Equals(Entry, other.Entry);
    }

    public override bool Equals(object obj)
    {
        if (ReferenceEquals(null, obj)) return false;
        return obj is InputEntry && Equals((InputEntry) obj);
    }

    public override int GetHashCode()
    {
        unchecked
        {
            return ( Date.GetHashCode()*397) 
                   ^ (Entry != null ? Entry.GetHashCode() 
                                    : 0);
        }
    }

    public static bool operator ==(InputEntry left, InputEntry right)
    {
        return left.Equals(right);
    }

    public static bool operator !=(InputEntry left, InputEntry right)
    {
        return !left.Equals(right);
    }

    private sealed class EntryDateEqualityComparer 
                                    : IEqualityComparer<InputEntry>
    {
        public bool Equals(InputEntry x, InputEntry y)
        {
            return string.Equals(x.Entry, y.Entry) && x.Date.Equals(y.Date);
        }

        public int GetHashCode(InputEntry obj)
        {
            unchecked
            {
                return ( (obj.Entry != null ? obj.Entry.GetHashCode() : 0)*397) 
                       ^ obj.Date.GetHashCode();
            }
        }
    }

    private static readonly IEqualityComparer<InputEntry> 
                  EntryDateComparerInstance = new EntryDateEqualityComparer();

    public static IEqualityComparer<InputEntry> EntryDateComparer
    {
        get { return EntryDateComparerInstance; }
    }
}



回答3:


Because they do not have the same type. You can try to cast them both to int, and then compare the ints, if the cast is successful.

public static bool Equals(object a, object b)
{
     try
     {
         return ((int)a).equals((int)b);
     }
     catch
     {
         return a.Equals(b);
     }
}


来源:https://stackoverflow.com/questions/25305393/why-does-objectint1-equalsobjectushort1-yield-false

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!