Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/290.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么这不起作用?(泛型等于辅助对象)_C#_Generics_Equals - Fatal编程技术网

C# 为什么这不起作用?(泛型等于辅助对象)

C# 为什么这不起作用?(泛型等于辅助对象),c#,generics,equals,C#,Generics,Equals,解决了 这是可行的,我需要告诉编译器T实现了IEquatable当然 public static bool secureEquals<T>(T obj1, object obj2) where T: class, IEquatable<T> {... public static bool secureEquals<T>(T obj1, T obj2) where T: class, IEquatable<T> {.... pub

解决了 这是可行的,我需要告诉编译器T实现了IEquatable当然

public static bool secureEquals<T>(T obj1, object obj2)
    where T: class, IEquatable<T>
{...

public static bool secureEquals<T>(T obj1, T obj2)
    where T: class, IEquatable<T>
{....
publicstaticboolsecureequals(T obj1,object obj2)
其中T:类,i可满足
{...
公共静态布尔secureEquals(T obj1,T obj2)
其中T:类,i可满足
{....

问题:

我尝试将IEquatable实现和Equals重写的重复功能放入一个单独的静态类中,如下所示:

public static class EqualsHelper
{
    public static bool secureEquals<T>(T obj1, object obj2)
       where T : class
    {
        if (obj2 is T)
        {
            return secureEquals(obj1, obj2 as T);
        }
        else
        {
            return false;
        }
    }

    public static bool secureEquals<T>(T obj1, T obj2)
    {
        if (obj1 == null)
        {
            if (obj2 != null)
                return false;
        }
        else
        {
            if (!obj1.Equals(obj2)) //this calls Dummy.Equals(object other)!
                return false;
        }

        return true;
    }


    public static bool secureEquals(double[] obj1, double[] obj2)
    {
        if (obj1.Length != obj2.Length)
            return false;

        for (int i = 0; i < obj1.Length; ++i)
        {
            if (obj1[i] != obj2[i])//ok for doubles if they are generated in the same way? I guess so!
                return false;
        }

        return true;
    }

public class Dummy : IEquatable<Dummy>
{
    public Dummy(string member)
    {
        _member = member;
    }

    private string _member;


    public virtual bool Equals(Dummy other)
    {
        return this._member == other._member;
    }

    public override bool Equals(object other)
    {
        return EqualsHelper.secureEquals(this, other);
    }

}

    static void Main(string[] args)
    {
        Dummy d1 = new Dummy("Hugo");
        Dummy d2 = new Dummy("Hugo");

        object d2obj = (object)d2;

        bool ret = d1.Equals(d2obj);
    }
公共静态类EqualsHelper
{
公共静态布尔secureEquals(T obj1,对象obj2)
T:在哪里上课
{
如果(obj2为T)
{
返回secureEquals(obj1,obj2为T);
}
其他的
{
返回false;
}
}
公共静态布尔secureEquals(T obj1,T obj2)
{
如果(obj1==null)
{
如果(obj2!=null)
返回false;
}
其他的
{
if(!obj1.Equals(obj2))//这将调用Dummy.Equals(object other)!
返回false;
}
返回true;
}
公共静态bool secureEquals(双[]对象J1,双[]对象J2)
{
如果(obj1.Length!=obj2.Length)
返回false;
对于(int i=0;i
这个想法是: d1.Equals(d2obj)调用Dummy.Equals(object)调用EqualsHelper.secureEquals(T,obj)调用EqualsHelper.secureEquals(T,T)调用Dummy.Equals(Dummy)

然而,最后一个调用调用Dummy.Equals(object),即使那里的所有内容都被键入了T

我错过了什么

PS:我知道用以下内容代替电话:

            if (!((IEquatable<T>)obj1).Equals(obj2)) //this calls Dummy.Equals(object other)!
if(!((IEquatable)obj1.Equals(obj2))//这将调用Dummy.Equals(object other)!

这是一个技巧,但是为什么它不起作用呢?

为什么:因为这里的方法调用是静态类型的,并且唯一可用的
等于
涉及
T
的方法是
对象。等于(对象)完全相同的IL必须能够处理<强>每一个< /强> <代码> t>代码> -c仿泛型不象C++模板;没有出现超-t过载的解决方案。

顺便说一下:您可能还想看看
EqualityComparer.Default.Equals(obj1,obj2)
,它将自动处理
IEquatable
null
,等等:

public static bool secureEquals<T>(T obj1, object obj2) where T : class
{
    return EqualityComparer<T>.Default.Equals(obj1, obj2 as T);
}
公共静态bool secureEquals(T obj1,对象obj2),其中T:class
{
返回EqualityComparer.Default.Equals(obj1,obj2为T);
}

编译
EqualsHelper
时,
Equals.secureEquals
中的
Equals
重载将被解决,而该代码不知道
t
是否实现了
IComparable
,因此剩下的就是
Equals(对象)
。您可以向
T
添加约束,使其使用正确的重载:

public static bool SecureEquals<T>(T obj1, T obj2) where T : IEquatable<T>
public static bool SecureEquals(T obj1,T obj2),其中T:IEquatable
当然,这会限制可以使用它的类


(顺便说一句,请注意我已将
secureEquals
重命名为
secureEquals
,以符合.NET命名约定。我个人也不会在这里使用“安全”一词-这里没有任何安全敏感信息。)

因为在您的
secureEquals
中没有约束,并且编译器总是假定Object.Equals存在。为您的T添加接口约束。

您的意思是
EqualityComparer.Default.Equals(…)
?使用EqualityComparer有什么好处?@B3ret因为它可以自动处理一些微妙的规则-例如,应用
IEquatable