c# - ImmutableHashSet .Contains returns false -
i have list (to precise immutablehashset<listitem>
system.collections.immutable) of base items , try call following code
_baselist.contains(deriveditem)
but returns false.
even though following code lines return true
object.referenceequals(_baselist.first(), deriveditem) object.equals(_baselist.first(), deriveditem) _baselist.first().gethashcode() == deriveditem.gethashcode()
i can write following , returns true:
_baselist.oftype<derivedclass>().contains(deriveditem)
what doing wrong, avoid writing .oftype stuff.
edit:
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 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 }
edit2:
here reproducible code of problem, seems immutablehashset<>
caches gethashcode
, doesn't compare current gethashcode
entries inside list, there way tell immutablehashset<>
gethashcode
of items different, atleast item checking since hey damn same reference...
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 5 - put should 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 { { 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) { } } }
if change immutablehashset<>
immutablelist<>
code works fine, if guys don't come idea switch list.
objects used in dictionaries , other hashing-related data structures should have immutable identity - hashing-related data structures assume once add object dictionary, hashcode not going change.
this code not going work:
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); } }
_baselist.contains()
in removeitem()
, called dostuff()
going return false every single item, because changed identity of stored item - basestring
property.
Comments
Post a Comment