如何确定两个通用类型值是否相等? [英] How to determine if two generic type values are equal?

查看:99
本文介绍了如何确定两个通用类型值是否相等?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

更新*
我很抱歉...我的示例代码包含一个错误,导致了很多答案,我不明白。
取代

Update* I am so sorry... my sample code contained an error which resulted in a lot of answers I didn't understand. In stead of

Console.WriteLine("3. this.Equals   " + (go1.Equals(go2)));

我打算写

Console.WriteLine("3. this.Equals   " + (go1.Equals(sb2)));






我想知道成功地确定两个通用类型值是否彼此相等。根据Mark Byers对此问题的回答我想我可以只使用 value.Equals()其中value是一个通用类型。
我的实际问题是在一个LinkedList实现,但问题可以用这个更简单的例子显示。


I'm trying to figure out how I can successfully determine if two generic type values are equal to each other. Based on Mark Byers' answer on this question I would think I can just use value.Equals() where value is a generic type. My actual problem is in a LinkedList implementation, but the problem can be shown with this simpler example.

class GenericOjbect<T> {
    public T Value { get; private set; }
    public GenericOjbect(T value) {
        Value = value;
    }
    public bool Equals(T value) {
        return (Value.Equals(value));
    }
}



现在我定义一个 GenericObject< StringBuilder> 包含 new StringBuilder(StackOverflow)。如果我在这个GenericObject实例上调用 Equals(new StringBuilder(StackOverflow),我希望得到 true 我得到 false

Now I define an instance of GenericObject<StringBuilder> containing new StringBuilder("StackOverflow"). I would expect to get true if I call Equals(new StringBuilder("StackOverflow") on this GenericObject instance, but I get false.

示例程序显示:

using System;
using System.Text;

class Program
{
    static void Main()
    {
        var sb1 = new StringBuilder("StackOverflow");
        var sb2 = new StringBuilder("StackOverflow");

        Console.WriteLine("StringBuilder compare");
        Console.WriteLine("1. ==            " + (sb1 == sb2));
        Console.WriteLine("2. Object.Equals " + (Object.Equals(sb1, sb2)));
        Console.WriteLine("3. this.Equals   " + (sb1.Equals(sb2)));

        var go1 = new GenericOjbect<StringBuilder>(sb1);
        var go2 = new GenericOjbect<StringBuilder>(sb2);

        Console.WriteLine("\nGenericObject compare");
        Console.WriteLine("1. ==            " + (go1 == go2));
        Console.WriteLine("2. Object.Equals " + (Object.Equals(go1, sb2)));
        Console.WriteLine("3. this.Equals   " + (go1.Equals(sb2)));
        Console.WriteLine("4. Value.Equals  " + (go1.Value.Equals(sb2.Value)));
    }
}

对于比较两个StringBuilder对象的三种方法, StringBuilder.Equals实例方法(第三行)返回 true 。这是我的期望。但是当比较GenericObject对象时,它的Equals()方法(第三行)返回 false 。有趣的是,第四个比较方法 返回 true 。我认为第三和第四个比较实际上是做同样的事情。

For the three methods of comparing two StringBuilder objects, only the StringBuilder.Equals instance method (the third line) returns true. This is what I expected. But when comparing the GenericObject objects, its Equals() method (the third line) returns false. Interestingly enough, the fourth compare method does return true. I'd think the third and fourth comparison are actually doing the same thing.

我会期望 true 。因为在GenericObject类的Equals()方法中, value Value 都是 T ,在本例中为 StringBuilder 。根据Mark Byers在此问题中的回答,我希望 Value.Equals()方法使用StringBuilder的Equals()方法。正如我所示,StringBuilder的Equal()方法会返回 true

I would have expected true. Because in the Equals() method of the GenericObject class, both value and Value are of type T which in this case is a StringBuilder. Based on Mark Byers' answer in this question, I would've expected the Value.Equals() method to be using the StringBuilder's Equals() method. And as I've shown, the StringBuilder's Equal() method does return true.

public bool Equals(T value) {
    return EqualityComparer<T>.Default.Equals(Value, value);
}

但也返回false。

这里有两个问题:


  1. 为什么代码不返回 true

  2. 如何实现等于方法, $ c> true ?

  1. Why doesn't the code return true?
  2. How could I implement the Equals method so it does return true?


推荐答案

href =http://stackoverflow.com/questions/4639443/how-to-determine-if-two-generic-type-values-are-equal/4639504#4639504> Marc Gravell的回答,问题是 StringBuilder 等于(对象)实现与中的不同Equals(StringBuilder )

As suggested in Marc Gravell's answer, the problem is with StringBuilder Equals(object) implementation that is different to the one in Equals(StringBuilder).

然后,您可以忽略该问题,因为您的代码将与任何其他一致地实现的类一起使用,解决问题(再次按照Mark Gravell的建议)。

Then, you can ignore the problem because your code will work with any other coherently-implemented classes, or you can use dynamic to fix the problem (again as suggested by Mark Gravell).

但是,由于你没有使用C#4(所以没有动态),你可以这样尝试:

But, given that you are not using C# 4 (so no dynamic), you can try in this way:

public bool Equals(T value)
{
   // uses Reflection to check if a Type-specific `Equals` exists...
   var specificEquals = typeof(T).GetMethod("Equals", new Type[] { typeof(T) });
   if (specificEquals != null &&
       specificEquals.ReturnType == typeof(bool))
   {
       return (bool)specificEquals.Invoke(this.Value, new object[]{value});
   }
   return this.Value.Equals(value);
}

这篇关于如何确定两个通用类型值是否相等?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆