c# - Deserializing .NET Dictionary using ISerializable -
i have problems getting de-/serialization of dictionary working when implementing iserializable in enclosing class. seems able automatically de-/serialize if apply serializableattribute. need check deserialized dictionary in process however, need iserializable working.
i set little test sure wasn't due other problems. test class looks this:
[serializable] class test : iserializable { private dictionary<string, int> _dict; public test() { var r = new random(); _dict = new dictionary<string, int>() { { "one", r.next(10) }, { "two", r.next(10) }, { "thr", r.next(10) }, { "fou", r.next(10) }, { "fiv", r.next(10) } }; } protected test(serializationinfo info, streamingcontext context) { // here _dict.count == 0 // found dictionary no content? _dict = (dictionary<string, int>)info.getvalue("foo", typeof(dictionary<string, int>)); } public void getobjectdata(serializationinfo info, streamingcontext context) { info.addvalue("foo", _dict, typeof(dictionary<string, int>)); } public override string tostring() { var sb = new stringbuilder(); foreach (var pair in _dict) sb.append(pair.key).append(" : ").append(pair.value).appendline(); return sb.tostring(); } }
and main test it:
static void main(string[] args) { var t1 = new test(); console.writeline(t1); var formatter = new binaryformatter(); using (var stream = new filestream("test.test", filemode.create, fileaccess.write, fileshare.none)) formatter.serialize(stream, t1); test t2; using (var stream = new filestream("test.test", filemode.open, fileaccess.read, fileshare.read)) t2 = (test)formatter.deserialize(stream); console.writeline(t2); console.readline(); }
the output in console same before , after. commented in test class, overloaded constructor doesn't read content in deserialized dictionary.
am doing wrong or bug/subtle side effect?
dictionary<tkey, tvalue>
implements ideserializationcallback
, defers completion of de-serialization until whole graph of objects read back. can see how implemented on reference source :
protected dictionary(serializationinfo info, streamingcontext context) { //we can't keys , values until entire graph has been deserialized //and have resonable estimate gethashcode not going fail. time being, //we'll cache this. graph not valid until ondeserialization has been called. hashhelpers.serializationinfotable.add(this, info); }
to force completion call _dict.ondeserialization()
in code:
protected test(serializationinfo info, streamingcontext context) { // here _dict.count == 0 // found dictionary no content? _dict = (dictionary<string, int>)info.getvalue("foo", typeof(dictionary<string, int>)); _dict.ondeserialization(null); // content restored. console.writeline("_dict.count={0}", _dict.count); }
ps: hashset<t>
, sortedset<t>
, linkedlist<t>
, maybe few other container types exhibit same behavior
Comments
Post a Comment