当_set是HashSet< T1&gt ;、 obj isT2和T1,T2都实现相同的接口时,如何测试_set.Contains(obj)? [英] How to test _set.Contains(obj), when _set is HashSet<T1>, obj isT2, and T1, T2 both implement same interface?

查看:89
本文介绍了当_set是HashSet< T1&gt ;、 obj isT2和T1,T2都实现相同的接口时,如何测试_set.Contains(obj)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我必须实现一个可以快速(O(1))测试对象存在的ObservableHashSet<T>:

I must implement an ObservableHashSet<T> that can quickly (O(1)) test for object existence:

public class ObservableHashSet<T> : ObservableCollection<T>{
    readonly ISet<T> _set = new HashSet<T>();

    protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e){
        base.OnCollectionChanged(e);
        if (e.Action == NotifyCollectionChangedAction.Move) return;

        if (e.OldItems != null)
            foreach (var old in e.OldItems.Cast<T>())
                _set.Remove(old.GetHashable());

        if (e.NewItems == null) return;

        foreach (var nu in e.NewItems.Cast<T>()) _set.Add(nu.GetHashable());
    }

    public bool QuickContains(T obj){ return _set.Contains(obj); }
}

现在说我们有两种类型,都实现相同的接口:

Now say we have two types, both implement same interface:

IDevice
  ├── ActualDevice
  └── DeviceClass

,界面为:

public interface IDevice {
    string Vendor { get; set; }
    string Name { get; set; }
}

我需要一种方法来快速(O(1))测试DeviceClass s(HashSet<DeviceClass>)列表中是否存在某些ActualDevice.那么如何更改上面的ObservableHashSet<T>.QuickContains(T obj)函数以允许它呢?所以我可以做这样的事情:

I need a way to quickly (O(1)) test for certain ActualDevice existence in a list of DeviceClasss (HashSet<DeviceClass>). So how can I change the ObservableHashSet<T>.QuickContains(T obj) function above to allow it? so I'd be able to do something like this:

var classesList = new ObservableHashSet<DeviceClass>(someDataSource);
ActualDevice actualDevice = GetTheDevice();
MessageBox.Show(classesList.QuickContains(actualDevice) ? "Exists!" : "Missing...");

推荐答案

我将HashSet<T>的项目类型设置为仅包含基于等式测试的数据的类.目前,您正在尝试将DeviceClass与等于ActualDevice的值进行比较,这似乎很奇怪.

I'd make the item type of the HashSet<T> a class that only contains the data that you base the equality test on. At the moment you are trying to make a DeviceClass compare equal to an ActualDevice which seems odd.

我的理解是,您想测试ActualDevice是否与许多DeviceClass之一相关联.您可以这样:

My understanding is that you want to test whether an ActualDevice is associated with one of many DeviceClass'es. You could do it like this:

class DeviceClassKey : IEquatable<DeviceClassKey> {

 //Data members here
 int DeviceClassID; /* just an example */

 public static DeviceClassKey FromDeviceClass(DeviceClass dc) { return ...; }
 public static DeviceClassKey FromActualDevice(ActualDevice ad) { return ...; }

 //add equality members here
}

现在您将成员添加到集合中,如下所示:

And now you add members to the set like this:

HashSet<DeviceClassKey> items = ...;
DeviceClass dc = ...;
items.Add(DeviceClassKey.FromDeviceClass(dc));

您可以像这样测试成员资格:

And you test membership like this:

HashSet<DeviceClassKey> items = ...;
ActualDevice ad = ...;
var isMember = items.Contains(DeviceClassKey.ActualDevice(ad));

我可能错过了您的一些要求,但是可以扩展这项技术来涵盖它.

I might have missed some requirement of yours but this technique can probably be extended to cover it.

这篇关于当_set是HashSet&lt; T1&gt ;、 obj isT2和T1,T2都实现相同的接口时,如何测试_set.Contains(obj)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆