【发布时间】:2015-06-04 13:17:41
【问题描述】:
我有一个基本项目列表(准确地说是来自 System.Collections.Immutable 的 ImmutableHashSet<ListItem>)并尝试调用以下代码
_baseList.Contains(derivedItem)
但这会返回 false。
即使以下代码行都返回 true
object.ReferenceEquals(_baseList.First(), derivedItem)
object.Equals(_baseList.First(), derivedItem)
_baseList.First().GetHashCode() == derivedItem.GetHashCode()
我什至可以写以下内容,它会返回 true:
_baseList.OfType<DerivedClass>().Contains(derivedItem)
我做错了什么,我想避免写 .OfType 的东西。
编辑:
private ImmutableHashSet<BaseClass> _baseList;
public class BaseClass
{
}
public class DerivedClass : BaseClass
{
}
public void DoStuff()
{
var items = _baseList.OfType<DerivedClass>().ToList();
foreach (var derivedItem in items)
{
RemoveItem(derivedItem);
}
}
public void RemoveItem(BaseClass derivedItem)
{
if (_baseList.Contains(derivedItem))
{
//doesn't reach this place, since _baseList.Contains(derivedItem) returns false...
_baseList = _baseList.Remove(derivedItem);
}
//object.ReferenceEquals(_baseList.First(), derivedItem) == true
//object.Equals(_baseList.First(), derivedItem) == true
//_baseList.First().GetHashCode() == derivedItem.GetHashCode() == true
//_baseList.OfType<DerivedClass>().Contains(derivedItem) == true
}
编辑2:
这是我的问题的可重现代码,似乎 ImmutableHashSet<> 缓存 GetHashCode 并且不会将当前的 GetHashCode 与列表中的条目进行比较,有没有办法告诉 ImmutableHashSet<> @987654330 @ of the items 可能会有所不同,至少对于我当前正在检查的项目,因为嘿,它是相同的参考...
namespace ConsoleApplication1
{
class Program
{
private static ImmutableHashSet<BaseClass> _baseList;
static void Main(string[] args)
{
_baseList = ImmutableHashSet.Create<BaseClass>();
_baseList = _baseList.Add(new DerivedClass("B1"));
_baseList = _baseList.Add(new DerivedClass("B2"));
_baseList = _baseList.Add(new DerivedClass("B3"));
_baseList = _baseList.Add(new DerivedClass("B4"));
_baseList = _baseList.Add(new DerivedClass("B5"));
DoStuff();
Console.WriteLine(_baseList.Count); //output is 5 - put it should be 0...
Console.ReadLine();
}
private static void DoStuff()
{
var items = _baseList.OfType<DerivedClass>().ToList();
foreach (var derivedItem in items)
{
derivedItem.BaseString += "Change...";
RemoveItem(derivedItem);
}
}
private static void RemoveItem(BaseClass derivedItem)
{
if (_baseList.Contains(derivedItem))
{
_baseList = _baseList.Remove(derivedItem);
}
}
}
public abstract class BaseClass
{
private string _baseString;
public string BaseString
{
get { return _baseString; }
set { _baseString = value; }
}
public BaseClass(string baseString)
{
_baseString = baseString;
}
public override int GetHashCode()
{
unchecked
{
int hashCode = (_baseString != null ? _baseString.GetHashCode() : 0);
return hashCode;
}
}
}
public class DerivedClass : BaseClass
{
public DerivedClass(string baseString)
: base(baseString)
{
}
}
}
如果我将 ImmutableHashSet<> 更改为 ImmutableList<> 代码可以正常工作,所以如果你们没有任何好主意,我将切换到列表。
【问题讨论】:
-
但它不只是失败,因为 baseList 充满了
ListItem,而您要搜索的对象是DerivedClass -
你是否重写了任何相等方法?
-
BaseClass和DerivedClass定义了哪些相等方法? HashSet中使用的KeyComparer是什么? -
@usr 是的,我确实覆盖了相等方法,但由于所有返回 true,应该没有问题,因为我使用的是 ImmutableHASHSET,它只检查相同的 GetHashCode 还是?
-
如果要改变内容,不可变集合的意义何在?这没有任何意义,没有什么能阻止我更改集合中每个项目的值!
标签: c# hashset immutable-collections