C# 为什么这不起作用?(泛型等于辅助对象)
解决了强> 这是可行的,我需要告诉编译器T实现了IEquatable当然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
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