@@ -9,6 +9,8 @@ namespace FastCloner.Code;
99
1010internal static class FastClonerExprGenerator
1111{
12+ internal static readonly ConcurrentDictionary < Type , Func < Type , bool , ExpressionPosition , object > > CustomTypeHandlers = [ ] ;
13+
1214 private static readonly ConcurrentDictionary < FieldInfo , bool > _readonlyFields = new ConcurrentDictionary < FieldInfo , bool > ( ) ;
1315
1416 private static readonly MethodInfo _fieldSetMethod ;
@@ -39,7 +41,7 @@ internal static void ForceSetField(FieldInfo field, object obj, object value)
3941 }
4042 }
4143
42- private readonly record struct ExpressionPosition ( int Depth , int Index )
44+ internal readonly record struct ExpressionPosition ( int Depth , int Index )
4345 {
4446 public ExpressionPosition Next ( ) => this with { Index = Index + 1 } ;
4547 public ExpressionPosition Nested ( ) => new ExpressionPosition ( Depth + 1 , 0 ) ;
@@ -62,7 +64,7 @@ private static LabelTarget CreateLoopLabel(ExpressionPosition position)
6264 {
6365 [ typeof ( ExpandoObject ) ] = ( _ , _ , position ) => GenerateExpandoObjectProcessor ( position ) ,
6466 [ typeof ( HttpRequestOptions ) ] = ( _ , _ , position ) => GenerateHttpRequestOptionsProcessor ( position ) ,
65- [ typeof ( Array ) ] = ( type , _ , _ ) => GenerateProcessArrayMethod ( type )
67+ [ typeof ( Array ) ] = ( type , _ , _ ) => GenerateProcessArrayMethod ( type ) ,
6668 } . ToFrozenDictionary ( ) ;
6769
6870 private static object GenerateProcessMethod ( Type type , bool unboxStruct , ExpressionPosition position )
@@ -71,6 +73,11 @@ private static object GenerateProcessMethod(Type type, bool unboxStruct, Express
7173 {
7274 return handler . Invoke ( type , unboxStruct , position ) ;
7375 }
76+
77+ if ( CustomTypeHandlers . TryGetValue ( type , out Func < Type , bool , ExpressionPosition , object > ? contribHandler ) )
78+ {
79+ return contribHandler . Invoke ( type , unboxStruct , position ) ;
80+ }
7481
7582 if ( IsDictionaryType ( type ) )
7683 {
0 commit comments