【发布时间】:2012-07-05 08:26:09
【问题描述】:
假设我有这样的课程:
public class MyClass {
public int Id { get; set;}
public string Name { get; set; }
}
请注意,在我的例子中,这个类是失控的(来自第三方库)并且没有实现相等比较器。
现在我想要一个这些项目的集合,允许我根据它们的索引删除项目。
我希望能够做到:
void Foo()
{
var collection = new MyClassCollection();
var a = new MyClass { Id = 1, Name = "A" };
var b = new MyClass { Id = 2, Name = "B" };
collection.Add(a);
collection.Add(b);
// Other instance, that can come from external code
var otherA = new MyClass { Id = 1, Name = "A" };
var otherB = new MyClass { Id = 2, Name = "B" };
collection.Remove(otherA);
Console.WriteLine(collection.Count); // should output 1
Console.WriteLine(collection.Contains(otherB)); // should be true
collection.Add(otherB); //
Console.WriteLine(collection.Count); // should still output 1
}
实际上,在集合中搜索时只应考虑 ID。此代码是依赖序列化 DTO 的项目的一部分,因此不能依赖实例。
我应该如何实现 MyClassCollection?
我想到了两种可能性,但对我来说都不是优雅的:
- 从
List<MyClass>继承并添加新方法。这将使 .Add 和 .Remove 保持原样,并可能导致消费者代码出现问题 - 创建一个实现
ICollection<MyClass>的类。创建一个内部Dictionary<int, MyClass>来存储值,并使用字典内置功能在添加或删除之前检查键。通过包装内部字典值来实现接口的所有方法
感谢您对我的案件的看法。
PS:我希望列表中的元素很少(
编辑:我使用的是 .Net 3.5 SP1。
Edit2:根据 Jon 的建议,这是我的实现:
public class MyClassCollection : HashSet<MyClass>
{
private class MyClassIDComparer : IEqualityComparer<MyClass>{
public bool Equals(MyClass x, MyClass y)
{
if (x == null && y == null) return true;
else if (x == null || y == null) return false;
else return x.ID == y.ID;
}
public int GetHashCode(MyClass obj)
{
return obj.ID.GetHashCode();
}
}
public MyClassCollection() : base(new MyClassIDComparer())
{
}
}
【问题讨论】:
标签: c# collections