Подтвердить что ты не робот

Почему ((object) (int) 1).Equals(((object) (ushort) 1)) дает false?

У меня есть ситуация, когда у меня есть object, который я хочу проверить на равенство с другим object.

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

Проблема возникает, когда a = 1 (integer) и b = 1 (ushort (or basically not integer)). Я задавался вопросом, не должно ли это быть истинным, но оно возвращает false...

Edit

Что еще хуже, так это:

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

Я думаю, что значение "1" должно быть разрешено только один раз.

4b9b3361

Ответ 1

Int32.Equals(object) возвращает true, только если другой объект также является экземпляром Int32:

true, если obj является экземпляром Int32 и равен значению этого пример; в противном случае - false.

В коде (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> (предпочтительно) или добавляли только ints к Hashtable.

Ответ 2

Вот простой класс и реализация сравнительных сравнений. Как вы можете видеть, стандартный apporach для equals состоит в том, чтобы убедиться, что они имеют одно и то же время, а затем, что внутренние совпадения (в нашем случае строка и дата).

Если вы хотите что-то еще, вы всегда можете переопределить его в своем сердечном содержимом и отбросить обе стороны к чему-то, что вам нравится:)

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

Потому что они не имеют одного и того же типа. Вы можете попытаться применить их как к int, так и затем сравнить ints, если приведение выполнено успешно.

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