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