@@ -10,6 +10,7 @@ namespace System.Activities;
1010using Expressions ;
1111using Internals ;
1212using Runtime ;
13+ using System . Collections . Concurrent ;
1314using Validation ;
1415
1516internal static class ActivityUtilities
@@ -47,6 +48,8 @@ internal static class ActivityUtilities
4748 private static readonly Type outArgumentOfObjectType = typeof ( OutArgument < object > ) ;
4849 private static readonly Type inOutArgumentOfObjectType = typeof ( InOutArgument < object > ) ;
4950 private static PropertyChangedEventArgs propertyChangedEventArgs ;
51+
52+ private static readonly ConcurrentDictionary < Type , ArgumentTypeInfo > argumentTypeCache = new ( ) ;
5053
5154 // Can't delay create this one because we use object.ReferenceEquals on it in WorkflowInstance
5255 private static readonly ReadOnlyDictionary < string , object > emptyParameters = new ( new Dictionary < string , object > ( 0 ) ) ;
@@ -97,31 +100,53 @@ public static bool IsInScope(ActivityInstance potentialChild, ActivityInstance s
97100
98101 public static bool IsCompletedState ( ActivityInstanceState state ) => state != ActivityInstanceState . Executing ;
99102
103+ private readonly struct ArgumentTypeInfo
104+ {
105+ public readonly ArgumentDirection Direction ;
106+ public readonly Type ArgumentType ;
107+
108+ public ArgumentTypeInfo ( ArgumentDirection direction , Type argumentType )
109+ {
110+ Direction = direction ;
111+ ArgumentType = argumentType ;
112+ }
113+ }
114+
100115 public static bool TryGetArgumentDirectionAndType ( Type propertyType , out ArgumentDirection direction , out Type argumentType )
101116 {
102117 direction = ArgumentDirection . In ; // default to In
103118 argumentType = TypeHelper . ObjectType ; // default to object
104119
105120 if ( propertyType . IsGenericType )
106121 {
122+ if ( argumentTypeCache . TryGetValue ( propertyType , out ArgumentTypeInfo info ) )
123+ {
124+ direction = info . Direction ;
125+ argumentType = info . ArgumentType ;
126+ return true ;
127+ }
128+
107129 argumentType = propertyType . GetGenericArguments ( ) [ 0 ] ;
108130
109131 Type genericType = propertyType . GetGenericTypeDefinition ( ) ;
110132
111133 if ( genericType == inArgumentGenericType )
112134 {
135+ argumentTypeCache . TryAdd ( propertyType , new ArgumentTypeInfo ( direction , argumentType ) ) ;
113136 return true ;
114137 }
115138
116139 if ( genericType == outArgumentGenericType )
117140 {
118141 direction = ArgumentDirection . Out ;
142+ argumentTypeCache . TryAdd ( propertyType , new ArgumentTypeInfo ( direction , argumentType ) ) ;
119143 return true ;
120144 }
121145
122146 if ( genericType == inOutArgumentGenericType )
123147 {
124148 direction = ArgumentDirection . InOut ;
149+ argumentTypeCache . TryAdd ( propertyType , new ArgumentTypeInfo ( direction , argumentType ) ) ;
125150 return true ;
126151 }
127152 }
0 commit comments