通用C#类中== vs Equals的性能

Opt*_*ion 9 c# generics performance operators

出于某种原因,C#不允许在这样的泛型类中使用==运算符:

class Mine<T> where T : struct
{
    T val;
    public T Value 
    { 
        set 
        { 
            if (val == value) // Operator '==' cannot be applied to operands of type T and T happens here
            {
                // .. do something ...
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

如果我用val.Equals(value)替换==我有代码按预期工作但如果我看字节码它看起来要复杂得多.使用==和Equals()比较循环中的int变量的一个非常简单的测试表明,Equals()版本比"=="版本慢两倍.

我想知道是否有一种方法来比较泛型类中的原始值类型,这些类型与==运算符一样快.欢迎任何想法.

编辑: 我在计时器之间迷路了.性能差异并不那么显着.这是我最新的结果:

== operator                            1974380 ticks
Equals()                               1976358 ticks
== operator in another static function 1974604 ticks
EqualityComparer<int>.Default...      32486695 ticks
Run Code Online (Sandbox Code Playgroud)

简而言之:Equals()足够好了.

Dmi*_*try 5

如果允许将IEquatable<T>约束添加到类中,则可以使用该IEquatable<T>.Equals(T other)接口中声明的方法:

class Mine<T> where T : struct, IEquatable<T>
{
    T val;
    public T Value
    {
        set
        {
            if (val.Equals(value)) // 
            {
                // .. do something ...
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


InB*_*een 5

原因是==默认引用相等并且对值类型没有意义,答案将始终是false. 因为没有语言机制来约束基于静态方法的泛型类型,编译器只是不允许这样做,因为它无法验证是否T真的有一个重载的==运算符。

在另一方面,如果你约束Tclass它,因为参考平等概念的意思是引用类型将编译就好了。

解决办法当然是IEquatable<T>; 在任何合理实现的结构中,IEquatable<T>.Equals(T t)都会为您提供价值相等的语义,并且==应该表现一致。

回答你的问题,不,没有。如果你真的需要速度,int == int你将需要实现一个非通用的专门类。