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年,我能过得轰轰烈烈点。

  • 相关阅读:
    从 OKR 工作法到 OKRs-E,落地OKR不能错过的转变
    OKR : 不要让目标仅仅成为口号
    [MySQL]Software caused connection abort: recv failed 问题分析与解决
    VS2010 vcpkgsrv.exe进程CPU占用高的解决方法
    Lync Server 2013企业版部署系列之九:前端部署后续工作
    Lync Server 2013企业版部署系列之八:安装lync server系统
    Lync Server 2013企业版部署系列之七:使用拓扑生成器规划拓扑
    Lync Server 2013企业版部署系列之六:AD准备
    Lync Server 2013企业版部署系列之五:前端服务器软件准备
    Lync Server 2013企业版部署系列之四:SQL准备
  • 原文地址:https://www.cnblogs.com/supperwu/p/4196028.html
Copyright © 2011-2022 走看看