首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用IEquatable接口

如何使用IEquatable接口
EN

Stack Overflow用户
提问于 2017-06-02 12:08:34
回答 3查看 381关注 0票数 2

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

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

代码语言:javascript
复制
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); }

}

但是,当我要调用时,我在编译中得到一个错误,我不太确定是否正确地调用了该方法:

代码语言:javascript
复制
int x = 2;
int y = 2;
Console.WriteLine(Test.IsEqual(x, y));

错误是:

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

编辑:我不太确定这段代码,但它能工作:

代码语言:javascript
复制
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‘’reilly”一书中读到了这句话

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2017-06-02 12:23:38

问题是int没有实现您的IEquatable<T>接口。

我在这里向您发布您的实现应该是什么样的,但是请考虑@MarcGravell在他的回答中解释了什么:

代码语言:javascript
复制
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);
票数 1
EN

Stack Overflow用户

发布于 2017-06-02 12:17:59

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

代码语言:javascript
复制
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确实为T==int实现了内置的System.IEquatable<T>,所以只需完全删除接口定义即可。

但是,您在这里所做的一切都是通过EqualityComparer<T>.Default做得更好。我建议:

代码语言:javascript
复制
class Test 
{
    public static bool IsEqual<T>(T a, T b)
       => EqualityComparer<T>.Default.Equals(a,b);
}

(请注意,您不需要泛型约束-它仍将正确工作-在可用时使用IEquatable<T>,而在其他情况下使用object.Equals --也包括nullNullable<T>等)。

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

代码语言:javascript
复制
Console.WriteLine(x == y);

当您只知道T (调用方提供T )时,应该使用一般的相等方法。

票数 3
EN

Stack Overflow用户

发布于 2017-06-02 12:26:38

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

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

代码语言:javascript
复制
public class Foo : IEquatable<ANY_TYPE>
{
...
}

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

代码语言:javascript
复制
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是您正在处理的泛型类型(有关更多信息,请参见https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/generics/generic-type-parameters )。

代码语言:javascript
复制
public class Foo<T> : IEquatable<T>
{
...
}

请记住,您还必须将等于方法的ANY_TYPE更改为T!

希望它能帮到你。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44328595

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档