6
我遇到了一個擴展方法,該方法適用於結構(SomeStruct)
並返回值是否等於default(SomeStruct)
(當調用無參數構造函數時)。比較結構而不用裝箱
public static bool IsDefault<T> (this T value)
where T : struct
{
return (!EqualityComparer<T>.Default.Equals(value, default(T)));
}
這讓我想知道結構是否被裝箱。這純粹是出於好奇心,因爲根據上下文的不同,拳擊/傳球的價值有利有弊。
假設:
- 第一下列方法是非法的,因爲結構不隱式重載相等運算
==/!=
。 - 第二個「出現」,以避免拳擊。
- 第三種方法應該始終打開結構體,因爲它調用了
object.Equals(object o)
。 - 第四有兩個過載可用
(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)));
}
這個問題是關於確認上述假設,如果我誤解和/或留下一些東西。
謝謝。所以我明白,第二種情況將需要拳擊,如果它不實施IEquatable?如果是這樣,那麼沒有消費者(結構的創建者)實現一個接口(進行更多的工作只是爲了消費我們的庫)而進行拆箱操作的方法都不是。 –
拳擊費用非常低,尤其是與典型的對象比較,所以我不會擔心它的實際情況。如果一個結構體的創建者沒有實現相等性,那麼它就按照Object.Equals給出的默認相等性,所以然後boxing是不可避免的,但是與(字節比較/反射)Object.Equals的成本。 – MicroVirus
Perf和成本是非常主觀的。我遇到過這樣的情景:即使是「自動公開財產」的成本,拳擊成本也遠遠超過了這些情況。就我而言,我不得不爲'Vector2'結構實現'public readonly'字段,這帶來了對背景字段屬性的一個荒謬的性能改進。但是這些都是專門的場景,開發人員已經足夠了解提供相關的內置比較。除此之外,你可以評論一下:「第二個案例將需要拳擊,如果它不實施IEquatable?」。 –