Почему ((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" должно быть разрешено только один раз.
Ответы
Ответ 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);
}
}