为什么((object)(int)1).Equals(((object)(ushort)1))产生错误?

时间:2014-08-14 10:06:19

标签: c# .net equality boxing

我的情况是我有一个object我想检查与另一个object的平等。

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

a = 1 (integer)b = 1 (ushort (or basically not integer))时出现问题。我想知道这不应该是真的,但它确实会返回错误......

修改

更糟糕的是:

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

我认为价值'1'应该只允许一次。

3 个答案:

答案 0 :(得分:19)

仅当另一个对象也是Int32的实例时,

Int32.Equals(object)才返回true:

  

如果obj是Int32的实例并且等于this的值,则返回true   实例;否则,错误。

在代码(ILSpy,.NET 4)中:

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

由于obj is int返回false,因此您获得false

修改:对您的编辑进行推广(Hashtable使用“类似”键):如果您不想允许重复的对象,请使用Dictionary<int, string>代替(首选)或仅添加HashTable的整数。

答案 1 :(得分:3)

这是一个简单的类和相等比较器的实现。 正如你所看到的,equals的标准apporach是确保它们首先是同一时间,然后是内部匹配(在我们的例子中是一个字符串和一个日期)。

如果您想要其他内容,您可以随时将其覆盖到您的心灵内容,并将双方置于您满意的地方:)

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

答案 2 :(得分:2)

因为它们没有相同的类型。 您可以尝试将它们都转换为int,然后比较int,如果转换成功。

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