11
11
using System . Collections ;
12
12
using System . Collections . Concurrent ;
13
13
using System . Collections . Generic ;
14
+ using System . Collections . ObjectModel ;
14
15
using System . Linq ;
15
16
using System . Reflection ;
16
17
using Hyperion . Extensions ;
@@ -45,6 +46,44 @@ public override ValueSerializer BuildSerializer(Serializer serializer, Type type
45
46
ObjectReader reader = ( stream , session ) =>
46
47
{
47
48
object instance ;
49
+
50
+ void ReadDictionaryKeyValuePairs ( object dictionaryInstance )
51
+ {
52
+ var count = stream . ReadInt32 ( session ) ;
53
+ for ( var i = 0 ; i < count ; i ++ )
54
+ {
55
+ var entry = stream . ReadObject ( session ) ; // KeyValuePair<TKey, TValue>
56
+
57
+ // Get entry.Key and entry.Value
58
+ var key = dictionaryTypes . KeyValuePairType . GetProperty ( nameof ( KeyValuePair < object , object > . Key ) ) . GetValue ( entry , null ) ;
59
+ var value = dictionaryTypes . KeyValuePairType . GetProperty ( nameof ( KeyValuePair < object , object > . Value ) ) . GetValue ( entry , null ) ;
60
+
61
+ // Same as: instance.Add(key, value)
62
+ dictionaryTypes . DictionaryInterfaceType
63
+ . GetMethod ( nameof ( IDictionary < object , object > . Add ) , new [ ] { dictionaryTypes . KeyType , dictionaryTypes . ValueType } )
64
+ . Invoke ( dictionaryInstance , new [ ] { key , value } ) ;
65
+ }
66
+ }
67
+
68
+ #region Special case for ReadOnlyDictionary
69
+ // Special case for ReadOnlyDictionary since ReadOnlyDictionary
70
+ // does not have a parameterless constructor
71
+ var genericReadOnlyDictionary = typeof ( ReadOnlyDictionary < , > ) ;
72
+ var readOnlyDictionaryType =
73
+ genericReadOnlyDictionary . MakeGenericType ( dictionaryTypes . KeyType , dictionaryTypes . ValueType ) ;
74
+ if ( type . Equals ( readOnlyDictionaryType ) )
75
+ {
76
+ var genericDictionary = typeof ( Dictionary < , > ) ;
77
+ var genericDictionaryType = genericDictionary . MakeGenericType ( dictionaryTypes . KeyType , dictionaryTypes . ValueType ) ;
78
+ var dictionary = Activator . CreateInstance ( genericDictionaryType ) ; // normal dictionary
79
+
80
+ ReadDictionaryKeyValuePairs ( dictionary ) ;
81
+ instance = Activator . CreateInstance ( type , dictionary ) ; // IDictionary<TKey, TValue>
82
+ if ( preserveObjectReferences ) session . TrackDeserializedObject ( instance ) ;
83
+ return instance ;
84
+ }
85
+ #endregion
86
+
48
87
try
49
88
{
50
89
instance = Activator . CreateInstance ( type , true ) ; // IDictionary<TKey, TValue>
@@ -56,20 +95,7 @@ public override ValueSerializer BuildSerializer(Serializer serializer, Type type
56
95
{
57
96
session . TrackDeserializedObject ( instance ) ;
58
97
}
59
- var count = stream . ReadInt32 ( session ) ;
60
- for ( var i = 0 ; i < count ; i ++ )
61
- {
62
- var entry = stream . ReadObject ( session ) ; // KeyValuePair<TKey, TValue>
63
-
64
- // Get entry.Key and entry.Value
65
- var key = dictionaryTypes . KeyValuePairType . GetProperty ( nameof ( KeyValuePair < object , object > . Key ) ) . GetValue ( entry , null ) ;
66
- var value = dictionaryTypes . KeyValuePairType . GetProperty ( nameof ( KeyValuePair < object , object > . Value ) ) . GetValue ( entry , null ) ;
67
-
68
- // Same as: instance.Add(key, value)
69
- dictionaryTypes . DictionaryInterfaceType
70
- . GetMethod ( nameof ( IDictionary < object , object > . Add ) , new [ ] { dictionaryTypes . KeyType , dictionaryTypes . ValueType } )
71
- . Invoke ( instance , new [ ] { key , value } ) ;
72
- }
98
+ ReadDictionaryKeyValuePairs ( instance ) ;
73
99
74
100
return instance ;
75
101
} ;
0 commit comments