44using System . Reflection ;
55using BinaryFormatter . TypeConverter ;
66using BinaryFormatter . Types ;
7+ using System . Collections ;
78
89namespace BinaryFormatter
910{
@@ -27,16 +28,24 @@ public class BinaryConverter
2728 [ typeof ( decimal ) ] = new DecimalConverter ( ) ,
2829 [ typeof ( string ) ] = new StringConverter ( ) ,
2930 [ typeof ( DateTime ) ] = new DatetimeConverter ( ) ,
30- [ typeof ( byte [ ] ) ] = new ByteArrayConverter ( )
31+ [ typeof ( byte [ ] ) ] = new ByteArrayConverter ( ) ,
32+ [ typeof ( IEnumerable ) ] = new IEnumerableConverter ( )
3133 } ;
3234
3335 public byte [ ] Serialize ( object obj )
3436 {
3537 Type t = obj . GetType ( ) ;
38+
3639 BaseTypeConverter converter ;
3740 if ( _converters . TryGetValue ( t , out converter ) )
3841 {
3942 return converter . Serialize ( obj ) ;
43+ } else if ( obj is IEnumerable )
44+ {
45+ if ( _converters . TryGetValue ( typeof ( IEnumerable ) , out converter ) )
46+ {
47+ return converter . Serialize ( obj ) ;
48+ }
4049 }
4150
4251 return SerializeProperties ( obj ) ;
@@ -63,25 +72,49 @@ private byte[] GetBytesFromProperty(object element)
6372 if ( element == null ) return new byte [ 0 ] ;
6473
6574 Type t = element . GetType ( ) ;
75+ BaseTypeConverter converter ;
6676 if ( _converters . ContainsKey ( t ) )
6777 {
68- BaseTypeConverter converter = _converters [ t ] ;
78+ converter = _converters [ t ] ;
6979 return converter . Serialize ( element ) ;
80+ } else if ( element is IEnumerable )
81+ {
82+ if ( _converters . TryGetValue ( typeof ( IEnumerable ) , out converter ) )
83+ {
84+ return converter . Serialize ( element ) ;
85+ }
7086 }
7187
72- // TODO serialize if IEnumerable
73-
7488 return SerializeProperties ( element ) ;
7589 }
7690
7791 public T Deserialize < T > ( byte [ ] stream )
7892 {
7993 Type type = typeof ( T ) ;
8094
95+ bool isEnumerableType = type . GetTypeInfo ( ) . ImplementedInterfaces
96+ . Where ( t => t == typeof ( IEnumerable ) ) . Count ( ) > 0 ;
97+
8198 BaseTypeConverter converter ;
8299 if ( _converters . TryGetValue ( type , out converter ) )
83100 {
84- return ( T ) converter . DeserializeToObject ( stream ) ;
101+ return ( T ) converter . DeserializeToObject ( stream ) ;
102+ } else if ( isEnumerableType )
103+ {
104+ if ( _converters . TryGetValue ( typeof ( IEnumerable ) , out converter ) )
105+ {
106+ var prepearedData = converter . DeserializeToObject ( stream ) as IEnumerable ;
107+
108+ var listType = typeof ( List < > ) ;
109+ var genericArgs = type . GenericTypeArguments ;
110+ var concreteType = listType . MakeGenericType ( genericArgs ) ;
111+ var data = Activator . CreateInstance ( concreteType ) ;
112+ foreach ( var item in prepearedData )
113+ {
114+ ( ( IList ) data ) . Add ( item ) ;
115+ }
116+ return ( T ) data ;
117+ }
85118 }
86119
87120 T instance = ( T ) Activator . CreateInstance ( type ) ;
@@ -116,8 +149,25 @@ private void DeserializeProperty<T>(PropertyInfo property, T instance, byte[] st
116149 offset += sizeof ( short ) ;
117150
118151 BaseTypeConverter converter = _converters . First ( x => x . Value . Type == type ) . Value ;
119- object data = converter . DeserializeToObject ( stream , ref offset ) ;
120- property . SetValue ( instance , data ) ;
152+ object data ;
153+ if ( type == SerializedType . IEnumerable )
154+ {
155+ var prepearedData = converter . DeserializeToObject ( stream , ref offset ) as IEnumerable ;
156+
157+ var prop = property ;
158+ var listType = typeof ( List < > ) ;
159+ var genericArgs = prop . PropertyType . GenericTypeArguments ;
160+ var concreteType = listType . MakeGenericType ( genericArgs ) ;
161+ data = Activator . CreateInstance ( concreteType ) ;
162+ foreach ( var item in prepearedData )
163+ {
164+ ( ( IList ) data ) . Add ( item ) ;
165+ }
166+ } else
167+ {
168+ data = converter . DeserializeToObject ( stream , ref offset ) ;
169+ }
170+ property . SetValue ( instance , data , property . GetIndexParameters ( ) ) ;
121171 }
122172 }
123173}
0 commit comments