如何使ObservableCollection中的项目唯一?

时间:2015-08-18 04:41:43

标签: c# collections

我正在使用以下内容填充可观察的集合:

var customers = new ObservableCollection<Customer>();

foreach (
    var customer in
        collListItem.Select(
            item =>
            new Customer
                {
                    Persona = item["Persona"].ToString(),
                    CustomerName = item["Title"].ToString()
                }))
{
    customers.Add(customer);
}

在使用此集合中的元素填充WPF数据网格之前,我想让它成为一个唯一的角色和客户列表(没有重复的行)。

我尝试使用以下内容:

customers = customers.Distinct();

但是我收到了错误:

  

无法转换来源类型   'System.Collections.Generic.IEnumerable到目标类型   “System.Collections.ObjectModel.ObservableCollection

我可以使用ObservableCollection的等效物吗?

3 个答案:

答案 0 :(得分:4)

由于Distinct返回的IEnumerable<T>不是ObservableCollection

如果你想要区分ObservableCollection,你应该再次创建它:

customers = new ObservableCollection<Customer>(customers.Distinct());

或者,作为变体,您可以立即修改查询并区分:

foreach (
var customer in
    collListItem.Select(
        item =>
        new Customer
            {
                Persona = item["Persona"].ToString(),
                CustomerName = item["Title"].ToString()
            }).Distinct())
{
    customers.Add(customer);
}

答案 1 :(得分:1)

这将无需在Customer

上实施您自己的比较
foreach (var customer in collListItem.Select(
            item => 
                new {
                    Persona = item["Persona"].ToString(),
                    CustomerName = item["Title"].ToString()
                }).Distinct()
                .Select(r => new Customer { Persona = r.Persona,
                                            CustomerName = r.CustomerName }))
{
    customers.Add(customer);
}

答案 2 :(得分:1)

这是一个古老的问题,但是我也面临着同样的问题,我认为我找到了另一种方法来完成OP的尝试。首先,我认为我们在这里面临着XY problem。 OP希望拥有一个包含唯一项的ObservableCollections,现在,两个答案都可以通过某种方式解决现有问题,但我认为这种方式不是最好的。

这应该是我们正在使用的数据结构的责任。如果该数据结构不存在,请创建它!

要求很明确:拥有一个包含唯一项的ObservableCollection。我的方法是从ObservableCollection继承并提供自定义逻辑来做到这一点:

public class ObservableUniqueCollection <T> : ObservableCollection<T>
{
    private readonly HashSet<T> _hashSet;

    public ObservableUniqueCollection() : this(EqualityComparer<T>.Default) { }

    public ObservableUniqueCollection(IEqualityComparer<T> equalityComparer) => _hashSet = new HashSet<T>(equalityComparer);

    public void AddRange(IEnumerable<T> items)
    {
        foreach (var item in items)
        {
            InsertItem(Count, item);
        }
    }

    protected override void InsertItem(int index, T item)
    {
        if (_hashSet.Add(item))
        {
            base.InsertItem(index, item);
        }
    }

    protected override void ClearItems()
    {
        base.ClearItems();
        _hashSet.Clear();
    }

    protected override void RemoveItem(int index)
    {
        var item = this [index];
        _hashSet.Remove(item);
        base.RemoveItem(index);
    }

    protected override void SetItem(int index, T item)
    {
        if (_hashSet.Add(item))
        {
            var oldItem = this[index];
            _hashSet.Remove(oldItem);
            base.SetItem(index, item);
        }
    }
}

因此,现在您不必担心集合中有重复项(只要您的类型实现IEquatable或提供IEqualityComparer)