.Equals上c#泛型方法中意外的行为 [英] Unexpected behavior in c# generic method on .Equals

查看:399
本文介绍了.Equals上c#泛型方法中意外的行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么Equals方法在泛型方法中返回不同的结果?我认为这里有一些自动装箱,我不明白。



下面是一个用.net 3.5或4.0重现行为的例子:

  static void Main(string [] args)
{
TimeZoneInfo tzOne = TimeZoneInfo.Local;
TimeZoneInfo tzTwo = TimeZoneInfo.FindSystemTimeZoneById(tzOne.StandardName);
Console.WriteLine(Compare(tzOne,tzTwo));
Console.WriteLine(tzOne.Equals(tzTwo));


private static Boolean比较< T>(T x,T y)
{
if(x!= null)
{
return x.Equals(y);
}
返回y == null;
}

输出:

 


编辑:
{
if(x!= null)
{
if(x是IEquatable< T>)
{
return(x as IEquatable< T>)等于(y)的。
}
return x.Equals(y);
}
返回y == null;






/ strong>:我提交了通过MS Connect的错误,它已经被解决,因此可能会在下一个.net框架版本中解决这个问题。如果它们可用,我会更新它的详细信息。



PS :这看起来是在.net 4.0及更高版本中修复的在mscorlib中反汇编TimeZoneInfo)。

解决方案

TimeZoneInfo不会覆盖Object Equals方法,因此它会调用默认的Object Equals ,这显然不能按预期工作。我会认为这是TimeZoneInfo中的一个错误。这应该可以工作:

pre $ private私人布尔比较< T>(T x,T y)
其中T:IEquatable< ; T>
{
if(x!= null)
{
return x.Equals(y);
}
返回false;

$ / code>

以上将导致它调用等于< T> ; ,这是你在上面调用的方法(它隐含地喜欢泛型调用,因为它比对象等式更具体的参数类型;但是在泛型方法中,它没有办法确保存在这样的通用Equals,因为没有限制保证这一点)。

Why does the Equals method return a different result from within the generic method? I think that there's some automatic boxing here that I don't understand.

Here's an example that reproduces the behavior with .net 3.5 or 4.0:

static void Main(string[] args)
{
    TimeZoneInfo tzOne = TimeZoneInfo.Local;
    TimeZoneInfo tzTwo = TimeZoneInfo.FindSystemTimeZoneById(tzOne.StandardName);
    Console.WriteLine(Compare(tzOne, tzTwo));
    Console.WriteLine(tzOne.Equals(tzTwo));
}

private static Boolean Compare<T>(T x, T y)
{
    if (x != null)
    {
        return x.Equals(y);
    }
    return y == null;
}

Output:

False
True

Edit: This code works as desired without many compromises:

private static Boolean Compare<T>(T x, T y)
{
    if (x != null)
    {
        if (x is IEquatable<T>)
        {
            return (x as IEquatable<T>).Equals(y);
        }
        return x.Equals(y);
    }
    return y == null;
}


Followup: I filed a bug via MS Connect and it has been resolved as fixed, so it's possible this will be fixed in the next version of the .net framework. I'll update with more details if they become available.

PS: This appears to be fixed in .net 4.0 and later (by looking at the disassembly of TimeZoneInfo in mscorlib).

解决方案

TimeZoneInfo does not override the Object Equals method, so it calls the default Object Equals, which apparently does not work as expected. I would consider this a bug in TimeZoneInfo. This should work:

private static Boolean Compare<T>(T x, T y)
        where T: IEquatable<T>
{
    if (x != null)
    {
        return x.Equals(y);
    }
    return false;
}

The above will cause it to call Equals<T>, which is the method you were calling above (it implicitly preferred the generic call because it was more specific to the parameter type than the Object Equals; inside the generic method, however, it had no way to be sure that such a generic Equals existed, since there was no constraint guaranteeing this).

这篇关于.Equals上c#泛型方法中意外的行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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