[英]Default Equality Comparison of Struct Wrapper types C#
C#參考指出,對於值類型:
ValueType.Equals(Object)方法將覆蓋Object.Equals(Object),並為.NET Framework中的所有值類型提供默認的值相等實現。
如果當前實例和obj的字段都不是引用類型,則Equals方法將對內存中的兩個對象進行逐字節比較。 否則,它將使用反射來比較obj和此實例的相應字段。
https://msdn.microsoft.com/zh-CN/library/2dts52z7(v=vs.110).aspx
既然這樣,因為int是一個值類型,所以我希望一個簡單的int包裝器就等於它包裝的int,因為在逐字節比較中它是相同的-它們都只包含一個int:
public struct Id
{
public Id(int id)
{
Id = id;
}
public int Id { get; }
}
Console.WriteLine(new Id(17).Equals(17);
但是它實際上打印錯誤。 為什么是這樣?
這些不是同一類型。 盡管文本沒有明確說明,但Equals
方法檢查它們是否為同一類型。
所以這可以工作:
new Id(17).Equals(new Id(17));
如果要在結構上處理兩種不同類型的比較,則需要重寫Equals
並自己處理。
相關來源是:
public abstract class ValueType {
[System.Security.SecuritySafeCritical]
public override bool Equals (Object obj) {
BCLDebug.Perf(false, "ValueType::Equals is not fast. "+this.GetType().FullName+" should override Equals(Object)");
if (null==obj) {
return false;
}
RuntimeType thisType = (RuntimeType)this.GetType();
RuntimeType thatType = (RuntimeType)obj.GetType();
if (thatType!=thisType) {
return false;
}
Object thisObj = (Object)this;
Object thisResult, thatResult;
// if there are no GC references in this object we can avoid reflection
// and do a fast memcmp
if (CanCompareBits(this))
return FastEqualsCheck(thisObj, obj);
FieldInfo[] thisFields = thisType.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
for (int i=0; i<thisFields.Length; i++) {
thisResult = ((RtFieldInfo)thisFields[i]).UnsafeGetValue(thisObj);
thatResult = ((RtFieldInfo)thisFields[i]).UnsafeGetValue(obj);
if (thisResult == null) {
if (thatResult != null)
return false;
}
else
if (!thisResult.Equals(thatResult)) {
return false;
}
}
return true;
}
如您所見,它在檢查字節之前先驗證參數的類型是否匹配。 由於您的類型不是int
,因此它將始終返回false。
通常,即使兩個對象都封裝相同的值,對象的Equals
方法也不會將其視為等於任何其他類型的對象。
由於重載,將某些類型的值傳遞給其他類型的Equals方法的行為可能導致它們轉換為與原始類型相同的類型。 例如, (16777216.0f).Equals(16777217)
將選擇重載Equals(float)
,將int
值16777217
轉換為最接近的float
值(即16777216.0f
),后者將依次等於16777216.0f
。 可以通過將兩個操作數轉換為object
來防止此行為,如((object)16777.216.0f).Equals(16777216)
或(16777.216.0f).Equals((object)16777216)
中的任何一個都將報告一個float
對象與int
對象不相等(即使它們具有相同的數值)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.