当_set是HashSet< T1> ;、 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?
问题描述
我必须实现一个可以快速(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 DeviceClass
s (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< T1> ;、 obj isT2和T1,T2都实现相同的接口时,如何测试_set.Contains(obj)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!