首先定义一个简单类,并重写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) == && String.Compare(x.Characterist, y.Characterist) == ;
} 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工具看个究竟了。如下图所示:

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

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

当匿名类型遇上Distinct的更多相关文章

  1. JavaScript中的匿名函数遇上!会怎么样

    通常,我们声明一个函数test){},可以通过test()来调用这个函数.但是,如果我们在这个函数声明的末尾加上(),解析器是无法理解的. function test(){ console.log(' ...

  2. 【C#复习总结】匿名类型由来

    1 属性 这得先从属性开始说,为什么外部代码访问对象内部的数据用属性而不是直接访问呢,这样岂不是更方便一些,但是事实证明直接访问是不安全的.那么,Anders Hejlsberg(安德斯·海尔斯伯格) ...

  3. Linq专题之提高编码效率—— 第二篇 神一样的匿名类型

    说起匿名类型,我们都知道这玩意都是为linq而生,而且匿名类型给我们带来的便利性大家在实战中应该都体会到了,特别适合于一次性使用,临时 使用这些场景,虽然说是匿名类型,也就是说是有类型的,只是匿名了而 ...

  4. 《精通C#》自定义类型转化-扩展方法-匿名类型-指针类型(11.3-11.6)

    1.类型转化在C#中有很多,常用的是int类型转string等,这些都有微软给我们定义好的,我们需要的时候直接调用就是了,这是值类型中的转化,有时候我们还会需要类类型(包括结构struct)的转化,还 ...

  5. 15.C#回顾及匿名类型(八章8.1-8.5)

    今天的篇幅应该会很长,除了回顾前面学的一些,还有写一些关于匿名类型的相关知识,总体上对后续的学习很有帮助,学好了,后面更容易理解,不明白的,那就前面多翻几次,看多了总是会理解的.那么,进入正题吧. 自 ...

  6. C#之匿名类型与隐式局部变量

    一.匿名类型 下面一段代码展示了如何定义并且使用匿名类型: static void Main(string[] args) { var patent1 = new { Title = "Ne ...

  7. 匿名类型(C# 编程指南)

    匿名类型提供了一种方便的方法,可用来将一组只读属性封装到单个对象中,而无需首先显式定义一个类型. 类型名由编译器生成,并且不能在源代码级使用.  每个属性的类型由编译器推断. 可通过使用 new 运算 ...

  8. [C#]匿名类型的深拷贝

    .net Framework 3.5 + C# 3 发布了包括LinQ等一系列功能,其中包括了匿名类型,而我们在升级到.net4后,发现原来写好的用于POCO的深拷贝方法 static object ...

  9. 如何把匿名类型.GetType()返回的对象传进泛型里面[转]

    //怎么取得匿名类型的Type放到 //泛型T当中?? var 匿名 = new { A = 0, B = 1 }; Type t = 匿名.GetType(); //然后下面 var xx = db ...

随机推荐

  1. Office组件之Spire.XLS的DotNet操作

    Overview 在项目中,我们经常需要将程序中获得的大量数据导出到Excel表格中,打印报表:进一步,还可能生成其折线图,对数据的变化趋势进行分析,从而更好地开展项目工作. 最近,我发现了一个对于D ...

  2. ESXi 强制4G内存解决(VMware ESXi 6.0.0.update02 )

    手上有个性能不太好的机器,想着装一个系统有点浪费,但是4G内存实际识别只有3.7G,到达不了EXSi的最低4G限制,无法安装.最终找到一个解决方法,经过验证适用于ESXi 6.0. 源自于:ESXi ...

  3. java socket 网络编程常见异常

    1.java.net.SocketTimeoutException 这个异常比较常见,socket超时.一般有2个地方会抛出这个,一个是connect的时候,这个超时参数由connect(Socket ...

  4. XE3随笔19:实例 - 借用 Google 实现全文翻译

    调用 Google 翻译的地址格式: http://ajax.googleapis.com/ajax/services/language/translate?v=1.0&q=" + ...

  5. mysql中的where和having子句的区别

    mysql中的where和having子句的区别 having的用法 having字句可以让我们筛选成组后的各种数据,where字句在聚合前先筛选记录,也就是说作用在group by和having字句 ...

  6. 5. Singleton(单例)

    意图: 保证一个类仅有一个实例,并提供一个访问它的全局访问点. 适用性: 当类只能有一个实例而且客户可以从一个众所周知的访问点访问它时. 当这个唯一实例应该是通过子类化可扩展的,并且客户应该无需更改代 ...

  7. 解决Visual Studio 2010闪退问题

    许多人都会面临这样的问题,vs2010闪退,明明程序执行成功,明明没有错误,缺闪了一下结束. 闪退问题主要是缓存的问题,通过在程序末尾,即main函数后增加 getchar(); getchar(); ...

  8. python核心编程笔记

    1.python的对象是通过引用传递的. 2.多元赋值: x, y = y, x

  9. 浅析 IDE跟编译器

    之前听别人总说你用啥IDE,直接用编译器. 总的来说IDE包含编译器,而编译器仅仅是IDE的一部分, IDE包括编辑器与编译器. IDE: 可以在IDE上面编写代码,然后编译运行,有错误还能调试.比如 ...

  10. 第一个jemter测试脚本

    通过jmeter代理录制脚本后,会产生大量的无用的请求,尽管在代理中已经过滤了一部分图片或者CSS.JS文件. 手动查看主要的请求:这里主要关注登陆请求,要确定有效的URL请求 删除除/Login.a ...