none
使用"=="符号判断两相同整型,在什么情况下会等于false?? RRS feed

  • 问题

  •     大家好!

        如题,问题是在扩展Distinct 方法的时候遇到的,具体扩展的代码如下:

       ComparerHelper静态类:

    public static class ComparerHelper { public static IEnumerable<TSource> DistinctEx<TSource>(this IEnumerable<TSource> sourse, Func<TSource, object> keySelector) { //return sourse.Distinct(new Comparer<TSource>((x, y) => keySelector(x).Equals(keySelector(y)))); return sourse.Distinct(new Comparer<TSource>((x, y) => keySelector(x) == (keySelector(y)))); }

    }

        Comparer类:
        public delegate bool EqualsComparer<T>(T x, T y);
    
        public class Comparer<T> : IEqualityComparer<T>
        {
            private EqualsComparer<T> _equalsComparer;
    
            public Comparer(EqualsComparer<T> equalsComparer)
            {
                this._equalsComparer = equalsComparer;
            }
    
            public bool Equals(T x, T y)
            {
                var tempValue = (this._equalsComparer != null) ? this._equalsComparer(x, y) : false;
                System.Diagnostics.Debug.WriteLine(string.Format("Equals Value: {0}", tempValue));
                return tempValue;
            }
    
            public int GetHashCode(T obj)
            {
                var tempHashCode = obj.ToString().GetHashCode();
                System.Diagnostics.Debug.WriteLine(string.Format("Hash Code: {0}", tempHashCode));
                return tempHashCode;
            }
        }

    调用的测试代码为: (测试数据里面两字段都肯定有重复数据的) 

    var distinctNameList = PresonList.DistinctEx(dto => dto.Name);  //Name为string类型
        var distinctAgeList = PresonList.DistinctEx(dto => dto.Age);   //Age为int类型

    结果是:

    使用DistinctEx方法的第一句代码实现时,两测试代码都是可以成功实现想要的效果的,

    但使用DistinctEx方法的第二句代码实现时,只有Name的过滤是正确的,Age的过滤无效(仍然会列出列表的所有项,此时的this._equalsComparer(x, y)总是false).

    因此就有如题所述的疑问.

    (ps:此扩展的实现是不好的,已换种方式了,只是对上述现象感觉到困惑,希望各位大大们指引一下!谢谢!)


    • 已编辑 UITu 2012年11月14日 3:50
    2012年11月14日 3:41

答案

  • 就我知道而言,问题可能出在这里:

    public static IEnumerable<TSource> DistinctEx<TSource>(this IEnumerable<TSource> sourse, Func<TSource, object> keySelector)

    注意我下划线部分——因为每次返回一个object,两个object对象永远不可能相同(除非重写了GetHashCode和Equal方法进行比较!)

    至于String,因为相同的String总是引用一份,重写了GethashCode和Equals方法,自然是相同的。

    我的建议(可以尝试任意一种):

    1)不要定义成object,而是定义泛型(因为静态扩展函数可以自我推断类型):

    public static IEnumerable<TSource,TType> DistinctEx<TSource>(this IEnumerable<TSource> sourse, Func<TSource, TType> keySelector)

    调用的时候:

    var distinctAgeList = PresonList.DistinctEx(dto => dto.Age);

    2)代码不变,这样做:

    var distinctAgeList = PresonList.DistinctEx(dto => dto.Age.ToString());


    我的博客园
    慈善点击,点击此处
    和谐拯救危机,全集下载,净化人心

    2012年11月14日 7:40
    版主

全部回复