首页 > C# > 我有一个枚举,并希望从中获得不同的值。

我有一个枚举,并希望从中获得不同的值。

上一篇 下一篇

是的,所以我有一个枚举,并希望从中获得不同的值。

当然,使用 ,还有一个名为 的扩展方法。在简单的情况下,它可以在没有参数的情况下使用,例如:System.LinqDistinct

var distinctValues = myStringList.Distinct();

很好,但是如果我有一个需要指定相等性的对象的枚举,则唯一可用的重载是:

var distinctValues = myCustomerList.Distinct(someEqualityComparer);

相等比较器参数必须是 的实例。当然,我可以这样做,但它有点冗长,而且很笨拙。IEqualityComparer<T>

我所期望的是一个需要lambda的重载,比如:Func<T, T, bool>

var distinctValues = myCustomerList.Distinct((c1, c2) => c1.CustomerId == c2.CustomerId);

有谁知道是否存在一些这样的扩展,或者一些等效的解决方法?还是我错过了什么?

或者,有没有办法指定内联(让我尴尬)?IEqualityComparer

更新

我找到了Anders Hejlsberg对MSDN论坛上关于此主题的帖子的回复。他说:

您将遇到的问题是,当两个对象比较
相等时,它们必须具有相同的 GetHashCode 返回值(否则 Distinct 内部使用的
哈希表将无法正常运行)。
我们使用IEqualityComparer,因为它将Equals和GetHashCode的兼容
实现打包到一个接口中。

我想这是有道理的。

分割线

网友回答:

在我看来,它就像你想要从 MoreLINQ 获得的。然后你可以写:DistinctBy

var distinctValues = myCustomerList.DistinctBy(c => c.CustomerId);

下面是一个精简版本(没有空性检查,也没有指定自己的键比较器的选项):DistinctBy

public static IEnumerable<TSource> DistinctBy<TSource, TKey>
     (this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
{
    HashSet<TKey> knownKeys = new HashSet<TKey>();
    foreach (TSource element in source)
    {
        if (knownKeys.Add(keySelector(element)))
        {
            yield return element;
        }
    }
}

分割线

网友回答:

IEnumerable<Customer> filteredList = originalList
  .GroupBy(customer => customer.CustomerId)
  .Select(group => group.First());

分割线

网友回答:

把事情包起来.我认为像我一样来到这里的大多数人都希望使用最简单的解决方案,而无需使用任何库并具有最佳性能

(我认为按方法接受的小组在性能方面是矫枉过正。

这是一个使用IEqualityComparer接口的简单扩展方法,它也适用于空值。

用法:

var filtered = taskList.DistinctBy(t => t.TaskExternalId).ToArray();

扩展方法代码

public static class LinqExtensions
{
    public static IEnumerable<T> DistinctBy<T, TKey>(this IEnumerable<T> items, Func<T, TKey> property)
    {
        GeneralPropertyComparer<T, TKey> comparer = new GeneralPropertyComparer<T,TKey>(property);
        return items.Distinct(comparer);
    }   
}
public class GeneralPropertyComparer<T,TKey> : IEqualityComparer<T>
{
    private Func<T, TKey> expr { get; set; }
    public GeneralPropertyComparer (Func<T, TKey> expr)
    {
        this.expr = expr;
    }
    public bool Equals(T left, T right)
    {
        var leftProp = expr.Invoke(left);
        var rightProp = expr.Invoke(right);
        if (leftProp == null && rightProp == null)
            return true;
        else if (leftProp == null ^ rightProp == null)
            return false;
        else
            return leftProp.Equals(rightProp);
    }
    public int GetHashCode(T obj)
    {
        var prop = expr.Invoke(obj);
        return (prop==null)? 0:prop.GetHashCode();
    }
}

模板简介:该模板名称为【我有一个枚举,并希望从中获得不同的值。】,大小是暂无信息,文档格式为.编程语言,推荐使用Sublime/Dreamweaver/HBuilder打开,作品中的图片,文字等数据均可修改,图片请在作品中选中图片替换即可,文字修改直接点击文字修改即可,您也可以新增或修改作品中的内容,该模板来自用户分享,如有侵权行为请联系网站客服处理。欢迎来懒人模板【C#】栏目查找您需要的精美模板。

相关搜索
  • 下载密码 lanrenmb
  • 下载次数 217次
  • 使用软件 Sublime/Dreamweaver/HBuilder
  • 文件格式 编程语言
  • 文件大小 暂无信息
  • 上传时间 03-09
  • 作者 网友投稿
  • 肖像权 人物画像及字体仅供参考
栏目分类 更多 >
热门推荐 更多 >
微信文章 微信图片 微信素材 企业网站 响应式 html5 微信模板 自适应 单页式简历模板 微信公众平台
您可能会喜欢的其他模板