@@ -1608,8 +1608,6 @@ public static object CreateInstance(Type type)
16081608 /// </summary>
16091609 static readonly Dictionary < Type , FastInvokeHandler > addHandlerCache = new Dictionary < Type , FastInvokeHandler > ( ) ;
16101610
1611- static readonly ReaderWriterLockSlim addHandlerCacheLock = new ReaderWriterLockSlim ( LockRecursionPolicy . SupportsRecursion ) ;
1612-
16131611 /// <summary>Makes a deep copy of any object</summary>
16141612 /// <typeparam name="T">The type of the instance that should be created</typeparam>
16151613 /// <param name="source">The original object</param>
@@ -1641,6 +1639,18 @@ public static void MakeDeepCopy<T>(object source, out T result, Func<string, Tra
16411639 ///
16421640 public static object MakeDeepCopy ( object source , Type resultType , Func < string , Traverse , Traverse , object > processor = null , string pathRoot = "" )
16431641 {
1642+ static bool TryGetHandler ( Type resultType , out FastInvokeHandler handler )
1643+ {
1644+ lock ( addHandlerCache )
1645+ return addHandlerCache . TryGetValue ( resultType , out handler ) ;
1646+ }
1647+
1648+ static void SetHandler ( Type resultType , FastInvokeHandler handler )
1649+ {
1650+ lock ( addHandlerCache )
1651+ addHandlerCache [ resultType ] = handler ;
1652+ }
1653+
16441654 if ( source is null || resultType is null )
16451655 return null ;
16461656
@@ -1655,44 +1665,30 @@ public static object MakeDeepCopy(object source, Type resultType, Func<string, T
16551665
16561666 if ( type . IsGenericType && resultType . IsGenericType )
16571667 {
1658- addHandlerCacheLock . EnterUpgradeableReadLock ( ) ;
1659- try
1668+ if ( ! TryGetHandler ( resultType , out var addInvoker ) )
16601669 {
1661- if ( ! addHandlerCache . TryGetValue ( resultType , out var addInvoker ) )
1662- {
1663- var addOperation = FirstMethod ( resultType , m => m . Name == "Add" && m . GetParameters ( ) . Length == 1 ) ;
1664- if ( addOperation is object )
1665- {
1666- addInvoker = MethodInvoker . GetHandler ( addOperation ) ;
1667- }
1668- addHandlerCacheLock . EnterWriteLock ( ) ;
1669- try
1670- {
1671- addHandlerCache [ resultType ] = addInvoker ;
1672- }
1673- finally
1674- {
1675- addHandlerCacheLock . ExitWriteLock ( ) ;
1676- }
1677- }
1678- if ( addInvoker != null )
1670+ var addOperation = FirstMethod ( resultType , m => m . Name == "Add" && m . GetParameters ( ) . Length == 1 ) ;
1671+ if ( addOperation is object )
16791672 {
1680- var addableResult = Activator . CreateInstance ( resultType ) ;
1681- var newElementType = resultType . GetGenericArguments ( ) [ 0 ] ;
1682- var i = 0 ;
1683- foreach ( var element in source as IEnumerable )
1684- {
1685- var iStr = ( i ++ ) . ToString ( ) ;
1686- var path = pathRoot . Length > 0 ? pathRoot + "." + iStr : iStr ;
1687- var newElement = MakeDeepCopy ( element , newElementType , processor , path ) ;
1688- _ = addInvoker ( addableResult , new object [ ] { newElement } ) ;
1689- }
1690- return addableResult ;
1673+ addInvoker = MethodInvoker . GetHandler ( addOperation ) ;
16911674 }
1675+
1676+ SetHandler ( resultType , addInvoker ) ;
16921677 }
1693- finally
1678+
1679+ if ( addInvoker != null )
16941680 {
1695- addHandlerCacheLock . ExitUpgradeableReadLock ( ) ;
1681+ var addableResult = Activator . CreateInstance ( resultType ) ;
1682+ var newElementType = resultType . GetGenericArguments ( ) [ 0 ] ;
1683+ var i = 0 ;
1684+ foreach ( var element in source as IEnumerable )
1685+ {
1686+ var iStr = ( i ++ ) . ToString ( ) ;
1687+ var path = pathRoot . Length > 0 ? pathRoot + "." + iStr : iStr ;
1688+ var newElement = MakeDeepCopy ( element , newElementType , processor , path ) ;
1689+ _ = addInvoker ( addableResult , new object [ ] { newElement } ) ;
1690+ }
1691+ return addableResult ;
16961692 }
16971693 }
16981694
0 commit comments