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?”。 –