C# 为什么((object)(int)1).Equals(((object)(ushort)1))会产生false?
我的情况是,我有一个C# 为什么((object)(int)1).Equals(((object)(ushort)1))会产生false?,c#,.net,equality,boxing,C#,.net,Equality,Boxing,我的情况是,我有一个对象,我想检查它是否与另一个对象相等 public static bool Equals(object a, object b) { return a.Equals(b); } 当A=1(整数)和b=1(ushort(或基本上不是整数))时会出现问题。我想知道这是否应该是真的,但它确实返回假 编辑 更糟糕的是: Hashtable ht = new Hashtable(); ht.Add((int)1, "SOME STRING"); ht.Add((short)1
对象
,我想检查它是否与另一个对象
相等
public static bool Equals(object a, object b)
{
return a.Equals(b);
}
当A=1(整数)
和b=1(ushort(或基本上不是整数))
时会出现问题。我想知道这是否应该是真的,但它确实返回假
编辑
更糟糕的是:
Hashtable ht = new Hashtable();
ht.Add((int)1, "SOME STRING");
ht.Add((short)1, "SOME STRING");
ht.Add((long)1, "SOME STRING");
我认为值“1”应该只允许一次。仅当另一个对象也是Int32
的实例时才返回true:
如果obj是Int32的实例,并且等于
实例;否则,错误
在代码(ILSpy
,.NET 4)中:
由于obj为int
返回false,因此得到一个false
Edit:使用“相似”键重新编辑(
Hashtable
):如果不想允许重复对象,请改用字典(首选)或仅向Hashtable
添加int 因为它们的类型不同。
如果转换成功,您可以尝试将它们都转换为int,然后比较int
public static bool Equals(object a, object b)
{
try
{
return ((int)a).equals((int)b);
}
catch
{
return a.Equals(b);
}
}
下面是一个简单的平等比较器类和实现。
如您所见,equals的标准用法是首先确保它们的时间相同,然后确保内部匹配(在我们的例子中,是字符串和日期)
如果你还想要别的东西,你可以随时随心所欲地将它覆盖,并在你满意的东西上投下两面性:)
public结构输入
{
公共日期时间日期{get;set;}
公共字符串项{get;set;}
公共布尔等于(输入其他)
{
返回日期.Equals(其他日期)和字符串.Equals(条目,其他条目);
}
公共覆盖布尔等于(对象对象对象)
{
if(ReferenceEquals(null,obj))返回false;
返回obj为inpuntery&&Equals((inpuntery)obj);
}
公共覆盖int GetHashCode()
{
未经检查
{
返回(Date.GetHashCode()*397)
^(Entry!=null?Entry.GetHashCode()
: 0);
}
}
公共静态布尔运算符==(输入左、输入右)
{
返回左。等于(右);
}
公共静态布尔运算符!=(输入左、输入右)
{
返回!左。等于(右);
}
私有密封类EntryDateEqualityComparer
:IEqualityComparer
{
公共布尔等于(inpuntery x,inpuntery y)
{
返回字符串.Equals(x.Entry,y.Entry)和&x.Date.Equals(y.Date);
}
public int GetHashCode(inpunterry obj)
{
未经检查
{
返回((obj.Entry!=null?obj.Entry.GetHashCode():0)*397)
^obj.Date.GetHashCode();
}
}
}
专用静态只读IEqualityComparer
EntryDateCompareInstance=new EntryDateEqualityComparer();
公共静态IEqualityComparer入口日期比较器
{
获取{return EntryDateCompareInstance;}
}
}
整数不是无符号的短整数ushort
。这就是为什么x.Equals(y)
为真很少是个好主意,但是x.GetType()==y.GetType()
为假。@JonSkeet有过吗?你有一个好主意的例子吗?@weston:我现在想不出任何例子,但我不喜欢完全被掩盖:)@JonSkeet我想这是一种礼貌的说法,说这从来都不是好主意:)@TimSchmelter你没有:)微软提供了,不需要反编译!这是没有用的。此方法的用户无法看到在方法内部对象被强制转换为int
。。。也是一次尝试{}只有我从未见过。只有try{}finally{}
或try{}catch{}[finally{}]
公平地说,我添加了catch,但他似乎想比较可以强制转换为int的类型,所以这可以解决他的问题。为什么他们需要看到在这个方法中,物体是被铸造的?因为相等是一种常见的物体方法,没有人会期望你的行为。他问为什么会这样,我告诉他,并告诉他他如何能使它不同,在我看来-1(显然):-)你没有告诉他为什么,因为这不是物体的相等,是你的习惯没有解释为什么在他的场景中失败。但是我将删除-1,因为您的代码正在运行。
public static bool Equals(object a, object b)
{
try
{
return ((int)a).equals((int)b);
}
catch
{
return a.Equals(b);
}
}
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; }
}
}