2016-04-24 44 views
6

我遇到了一個擴展方法,該方法適用於結構(SomeStruct)並返回值是否等於default(SomeStruct)(當調用無參數構造函數時)。比較結構而不用裝箱

public static bool IsDefault<T> (this T value) 
    where T : struct 
{ 
    return (!EqualityComparer<T>.Default.Equals(value, default(T))); 
} 

這讓我想知道結構是否被裝箱。這純粹是出於好奇心,因爲根據上下文的不同,拳擊/傳球的價值有利有弊。

假設:

  1. 第一下列方法是非法的,因爲結構不隱式重載相等運算==/!=
  2. 第二個「出現」,以避免拳擊。
  3. 第三種方法應該始終打開結構體,因爲它調用了object.Equals(object o)
  4. 第四有兩個過載可用(object/T)所以我假設它也會避免拳擊。但是,目標結構需要實現IEquatable<T>接口,使輔助擴展方法不是很有幫助。

變化:

public static bool IsDefault<T> (this T value) 
    where T : struct 
{ 
    // Illegal since there is no way to know whether T implements the ==/!= operators. 
    return (value == default(T)); 
} 

public static bool IsDefault<T> (this T value) 
    where T : struct 
{ 
    return (!EqualityComparer<T>.Default.Equals(value, default(T))); 
} 

public static bool IsDefault<T> (this T value) 
    where T : struct 
{ 
    return (value.Equals(default(T))); 
} 

public static bool IsDefault<T> (this T value) 
    where T : struct, IEquatable<T> 
{ 
    return (value.Equals(default(T))); 
} 

這個問題是關於確認上述假設,如果我誤解和/或留下一些東西。

回答

4
  1. 第一下列方法是非法的,因爲結構不隱含重寫等式運算符== /!=。

是的。

  1. 第二個「出現」以避免拳擊。

的調用方法的簽名是EqualityComparer<T>.Equals(T,T)它使用類型T的參數,所以它不需要拳擊打電話。

('只在需要

默認的比較檢查的實施,如果 TIEquatable<T>,如果是使用使用 IEquatable<T>.Equals和其他一個比較器用來 Object.Equals一個比較器,所以在內部有可能是拳擊應用,如果結構不 IEquatable 「)。

  • 第三種方法應該總是框中的結構,因爲它調用的Object.Equals(對象o)。
  • 是的。

    1. 第四個有兩個重載可用(object/T),所以我假設它也會避免裝箱。但是,目標結構將需要實現IEquatable接口,使輔助擴展方法不是很有幫助。

    是,它不需要拳擊,按this SO answer。這是您從EqualityComparer<T>.Default針對T : IEquatable的特定情況獲得的有效代碼。

    +0

    謝謝。所以我明白,第二種情況將需要拳擊,如果它不實施IEquatable ?如果是這樣,那麼沒有消費者(結構的創建者)實現一個接口(進行更多的工作只是爲了消費我們的庫)而進行拆箱操作的方法都不是。 –

    +1

    拳擊費用非常低,尤其是與典型的對象比較,所以我不會擔心它的實際情況。如果一個結構體的創建者沒有實現相等性,那麼它就按照Object.Equals給出的默認相等性,所以然後boxing是不可避免的,但是與(字節比較/反射)Object.Equals的成本。 – MicroVirus

    +0

    Perf和成本是非常主觀的。我遇到過這樣的情景:即使是「自動公開財產」的成本,拳擊成本也遠遠超過了這些情況。就我而言,我不得不爲'Vector2'結構實現'public readonly'字段,這帶來了對背景字段屬性的一個荒謬的性能改進。但是這些都是專門的場景,開發人員已經足夠了解提供相關的內置比較。除此之外,你可以評論一下:「第二個案例將需要拳擊,如果它不實施IEquatable ?」。 –