LINQ命名空间下的Distinct方法有两个重载,一个是对TSource的Queryable可查询结果集支持的,别一个是只对T的IList,Enumerable结果集支持的
看一下,如果是返回为iqueryable<T>结果集,只能用distinct()默认的方法,
如果是List<T>,就可以根据自己定义好的比较原则,进行字段级的过滤了
例如,可以对Person类,进行ID,与Name的相等来确实整个对象是否与其它实例对象相等:
public class Person
{
public int ID { get; set; }
public string Name { get; set; }
public string Email { get; set; }
}
public class PersonCompar : System.Collections.Generic.IEqualityComparer<Person>
{
public bool Equals(Person x, Person y)
{
if (x == null)
return y == null;
return x.ID == y.ID;
}
public int GetHashCode(Person obj)
{
if (obj == null)
return 0;
return obj.ID.GetHashCode();
}
}
如果一个list<person>的实例为
personList,那么,它根据ID过滤的程序为
personList.Distinct(new PropertyComparer<Person>("ID")).ToList().ForEach(i => Console.WriteLine(i.ID + i.Name));
PropertyComparer.cs代码如下
/// <summary>
/// 属性比较器
/// </summary>
/// <typeparam name="T"></typeparam>
public class PropertyComparer<T> : IEqualityComparer<T>
{
private PropertyInfo _PropertyInfo;
/// <summary>
/// 通过propertyName 获取PropertyInfo对象 /// </summary>
/// <param name="propertyName"></param>
public PropertyComparer(string propertyName)
{
_PropertyInfo = typeof(T).GetProperty(propertyName,
BindingFlags.GetProperty | BindingFlags.Instance | BindingFlags.Public);
if (_PropertyInfo == null)
{
throw new ArgumentException(string.Format("{0} is not a property of type {1}.",
propertyName, typeof(T)));
}
}
#region IEqualityComparer<T> Members
public bool Equals(T x, T y)
{
object xValue = _PropertyInfo.GetValue(x, null);
object yValue = _PropertyInfo.GetValue(y, null);
if (xValue == null)
return yValue == null;
return xValue.Equals(yValue);
}
public int GetHashCode(T obj)
{
object propertyValue = _PropertyInfo.GetValue(obj, null);
if (propertyValue == null)
return 0;
else
return propertyValue.GetHashCode();
}
#endregion
}