我如何使用IEquatable接口

时间:2017-06-02 12:08:34

标签: c# interface

我正在研究接口的类型,但我不明白如何使用 IEquatable接口

我认为它提供了比直接使用 a.Equals(b)更好的性能,因为我们避免装箱......我已经这样做了:

public interface IEquatable<T> { bool Equals(T other); }
class Test<T> where T:IEquatable<T>
{
    public static bool IsEqual(T a, T b) { return a.Equals(b); }

}

但是当我要打电话时,我在编辑中遇到错误,我不确定我是否正确调用该方法:

int x = 2;
int y = 2;
Console.WriteLine(Test.IsEqual(x, y));

错误是:

  

错误CS0305使用泛型类型'Test'需要1个类型参数

编辑:我对这段代码不是很确定,但它有效:

class Test<T> where T:IEquatable<T>
    {
        public static bool Equals(T a, T b)
        {
            return a.Equals(b);

        }
    }


    class Program
    {
        static void Main(string[] args)
        {
            int x = 2;
            int y = 2;

            bool check = Test<int>.Equals(x, y);
            Console.WriteLine(check);
            Console.ReadKey();
        }
    }

我何时必须使用此代码?,我在 C#6 Nutshell O'reilly

一书中读到了这一点。

3 个答案:

答案 0 :(得分:3)

Test 不是 - 只有Test<T>。您可以做的第一件事是使类型非泛型,方法泛型:

class Test 
{
    public static bool IsEqual<T>(T a, T b)
        where T : IEquatable<T>
    { return a.Equals(b); }
}

请注意,这仍然不是很好 - 它不会a作为null正常工作,但是......这并不重要,因为它仍然无法帮助您,因为int并未真正实现您的 IEquatable<T>。它看起来不正确 - 它必须正式实现界面。幸运的是,int System.IEquatable<T>实现内置 T==int,所以只需完全删除您的界面定义。

但是,您在此处所做的一切都由EqualityComparer<T>.Default做得更好。我建议:

class Test 
{
    public static bool IsEqual<T>(T a, T b)
       => EqualityComparer<T>.Default.Equals(a,b);
}

(请注意,您不需要通用约束 - 它仍可正常运行,在可用时使用IEquatable<T> ,否则使用object.Equals - 也会占用nullNullable<T>等。)

注意:如果真的只是在这里使用int,那么您应该只使用==

Console.WriteLine(x == y);

当您只知道T时,应使用通用的平等方法,其中来电者提供T

答案 1 :(得分:2)

问题是int没有实现您的IEquatable<T>界面。

在这里,我将向您介绍您的实施应该如何,但请考虑@MarcGravell在其答案中解释的内容:

public interface IEquatable<T>
{
    bool Equals(T other);
}

public class MyInt : IEquatable<MyInt> //you need an actual implementor of IEquatable<T>
{
    public int Value { get; set; }


    public bool Equals(MyInt other)
    {
        return Value.Equals(other);
    }
}

class Test
{
    public static bool IsEqual<T>(T a, T b) where T : IEquatable<T>
    {
        // Ensure your Equals implementation is used
        return a.Equals(b);
    }
}

var x = new MyInt { Value = 2 };
var y = new MyInt { Value = 3 };
Test.IsEqual(x, y);

答案 2 :(得分:2)

您可以创建一个继承 IEquatable 的类。就像这样:

请注意,您必须定义ANY_TYPE。例如,它可以是字符串,int或DateTime。

public class Foo : IEquatable<ANY_TYPE>
{
...
}

现在因为你继承了一个提供方法的接口,你必须实现它。 只需将此函数放入类中:

public bool Equals(ANY_TYPE other)
{
    if(other == null)return false; // Dont run into null reference trouble!
    bool isSame = this == other; // or what ever you want to compare
    return isSame;
}

您也可以使用通用类型。像这样创建你的类:

T是您正在处理的通用类型(有关详细信息,请参阅msdn generic types

public class Foo<T> : IEquatable<T>
{
...
}

请注意,您必须将等于平均方法的 ANY_TYPE 更改为T!

我希望它可以帮到你。