zoukankan      html  css  js  c++  java
  • 当匿名类型遇上Distinct

    首先定义一个简单类,并重写ToString方法。

    public class CommidityFilter
        {
            public string Property { get; set; }
            public string Characterist { get; set; }
    
            public override string ToString()
            {
                return string.Format("Property:{0},Characterist:{1}", this.Property, this.Characterist);
            }
        }

    然后手动生成一个IEnumerable<CommidityFilter>集合。

    private static IEnumerable<CommidityFilter> GetCommidityFilters()
            {
                var result = new List<CommidityFilter>
                    {
                        new CommidityFilter {Property = "Size",Characterist = "L"},
                        new CommidityFilter {Property = "Size",Characterist = "L"},
                        new CommidityFilter {Property = "Size",Characterist = "XL"},
                        new CommidityFilter {Property = "Color",Characterist = "Red"},
                        new CommidityFilter {Property = "Color",Characterist = "Yellow"},
                        new CommidityFilter {Property = "Color",Characterist = "Red"}
                    };
    
                return result;
            }

    现在要做的是对整个集合进行过滤,去掉重复的CommidityFilter,通常都会用Distinct扩展方法。要对CommidityFilter集合去掉重复项,一共有两种方法。

    1:重写CommidityFilter的Equals、GetHashCode方法。

    2:Distinct方法指定一个实现了IEqualityComparer接口的对象。

    这里我们采用第二种方法,首先来实现CommidityFilterComparer

    public class CommidityFilterComparer : IEqualityComparer<CommidityFilter>
        {
            public bool Equals(CommidityFilter x, CommidityFilter y)
            {
                if (x == null || y == null)
                    return false;
                return String.Compare(x.Property, y.Property) == 0 && String.Compare(x.Characterist, y.Characterist) == 0;
            }
    
            public int GetHashCode(CommidityFilter obj)
            {
                return obj.Property.GetHashCode() ^ obj.Characterist.GetHashCode();
            }
        }

    然后实现去掉重复项的代码:

    var result = GetCommidityFilters();
    var filters = result.Distinct(new CommidityFilterComparer()).ToArray();
    Array.ForEach(filters, Console.WriteLine);

    输出的结果如下:

    Property:Size,Characterist:L

    Property:Size,Characterist:XL

    Property:Size,Characterist:Red

    Property:Size,Characterist:Yellow

    上面完美的实现了想要的结果,但是开发经常遇到的情况是GetCommidityFilters方法返回的集合中的CommidityFilter可能不只是Property,Characterist两个属性,比方还有其他的OtherProperty属性。而前端的ViewModel只需要去掉重复项后Property,Characterist两个属性。在这种情况下,通常会选择用匿名类型。现在来重新定义下CommidityFilter类、以及GetCommidityFilters方法。

    public class CommidityFilter
        {
            public string Property { get; set; }
            public string Characterist { get; set; }
            public string OtherProperty { get; set; }
    
            public override string ToString()
            {
                return string.Format("Property:{0},Characterist:{1}", this.Property, this.Characterist);
            }
        }
    private static IEnumerable<CommidityFilter> GetCommidityFilters()
            {
                var result = new List<CommidityFilter>
                    {
                        new CommidityFilter {Property = "Size",Characterist = "L",OtherProperty = "A"},
                        new CommidityFilter {Property = "Size",Characterist = "L",OtherProperty = "B"},
                        new CommidityFilter {Property = "Size",Characterist = "XL",OtherProperty = "C"},
                        new CommidityFilter {Property = "Color",Characterist = "Red",OtherProperty = "D"},
                        new CommidityFilter {Property = "Color",Characterist = "Yellow",OtherProperty = "E"},
                        new CommidityFilter {Property = "Color",Characterist = "Red",OtherProperty = "F"}
                    };
    
                return result;
            }

    接下来,再来实现去掉重复项的代码。

    var result = GetCommidityFilters();
                var filters = result.Select(e => new
                    {
                        Property = e.Property, 
                        Characterist = e.Characterist
                    }).Distinct().ToArray();
                Array.ForEach(filters, Console.WriteLine);

    输出的结果如下:

    {Property = Size,Characterist = L}

    {Property = Size,Characterist = XL}

    {Property = Size,Characterist = Red}

    {Property = Size,Characterist = Yellow}

    在上面实现的去重复项代码中,并没有为Distinct扩展方法指定一个实现了IEqualityComparer接口的对象,还是很完美的去掉的重复项。这是为什么呢?只能借助于IL DASM工具看个究竟了。如下图所示:

    20141231163005

    原来C#编译器会在背后默默的给所有的匿名类型重写Equals,GetHashCode,ToString三个方法,也就是说对匿名类型的集合使用Distinct过滤重复项,默认就是上面提到的第一种方法。

    2014年就要过去了,我的2014相比2013年来说过的有点平庸,在最后一天才写了这年的第一篇随笔,希望2015年,我能过得轰轰烈烈点。

  • 相关阅读:
    Codeforces 177G2 Fibonacci Strings KMP 矩阵
    Codeforces Gym100187C Very Spacious Office 贪心 堆
    Codeforces 980F Cactus to Tree 仙人掌 Tarjan 树形dp 单调队列
    AtCoder SoundHound Inc. Programming Contest 2018 E + Graph (soundhound2018_summer_qual_e)
    BZOJ3622 已经没有什么好害怕的了 动态规划 容斥原理 组合数学
    NOIP2016提高组Day1T2 天天爱跑步 树链剖分 LCA 倍增 差分
    Codeforces 555C Case of Chocolate 其他
    NOIP2017提高组Day2T3 列队 洛谷P3960 线段树
    NOIP2017提高组Day2T2 宝藏 洛谷P3959 状压dp
    NOIP2017提高组Day1T3 逛公园 洛谷P3953 Tarjan 强连通缩点 SPFA 动态规划 最短路 拓扑序
  • 原文地址:https://www.cnblogs.com/supperwu/p/4196028.html
Copyright © 2011-2022 走看看