@@ -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,55 +100,82 @@ 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 bool IsArgument ;
106+ public readonly ArgumentDirection Direction ;
107+ public readonly Type ArgumentType ;
108+
109+ public ArgumentTypeInfo ( bool isArgument , ArgumentDirection direction , Type argumentType )
110+ {
111+ IsArgument = isArgument ;
112+ Direction = direction ;
113+ ArgumentType = argumentType ;
114+ }
115+ }
116+
100117 public static bool TryGetArgumentDirectionAndType ( Type propertyType , out ArgumentDirection direction , out Type argumentType )
101118 {
102- direction = ArgumentDirection . In ; // default to In
103- argumentType = TypeHelper . ObjectType ; // default to object
119+ if ( argumentTypeCache . TryGetValue ( propertyType , out ArgumentTypeInfo info ) )
120+ {
121+ direction = info . Direction ;
122+ argumentType = info . ArgumentType ;
123+ return info . IsArgument ;
124+ }
125+
126+ bool isArgument = false ;
127+ direction = ArgumentDirection . In ;
128+ argumentType = TypeHelper . ObjectType ;
104129
105130 if ( propertyType . IsGenericType )
106131 {
107- argumentType = propertyType . GetGenericArguments ( ) [ 0 ] ;
108-
109132 Type genericType = propertyType . GetGenericTypeDefinition ( ) ;
110133
111134 if ( genericType == inArgumentGenericType )
112135 {
113- return true ;
136+ direction = ArgumentDirection . In ;
137+ argumentType = propertyType . GetGenericArguments ( ) [ 0 ] ;
138+ isArgument = true ;
114139 }
115-
116- if ( genericType == outArgumentGenericType )
140+ else if ( genericType == outArgumentGenericType )
117141 {
118142 direction = ArgumentDirection . Out ;
119- return true ;
143+ argumentType = propertyType . GetGenericArguments ( ) [ 0 ] ;
144+ isArgument = true ;
120145 }
121-
122- if ( genericType == inOutArgumentGenericType )
146+ else if ( genericType == inOutArgumentGenericType )
123147 {
124148 direction = ArgumentDirection . InOut ;
125- return true ;
149+ argumentType = propertyType . GetGenericArguments ( ) [ 0 ] ;
150+ isArgument = true ;
126151 }
127152 }
128153 else
129154 {
130155 if ( propertyType == inArgumentType )
131156 {
132- return true ;
157+ direction = ArgumentDirection . In ;
158+ argumentType = TypeHelper . ObjectType ;
159+ isArgument = true ;
133160 }
134-
135- if ( propertyType == outArgumentType )
161+ else if ( propertyType == outArgumentType )
136162 {
137163 direction = ArgumentDirection . Out ;
138- return true ;
164+ argumentType = TypeHelper . ObjectType ;
165+ isArgument = true ;
139166 }
140-
141- if ( propertyType == inOutArgumentType )
167+ else if ( propertyType == inOutArgumentType )
142168 {
143169 direction = ArgumentDirection . InOut ;
144- return true ;
170+ argumentType = TypeHelper . ObjectType ;
171+ isArgument = true ;
145172 }
146173 }
147174
148- return false ;
175+ var newInfo = new ArgumentTypeInfo ( isArgument , direction , argumentType ) ;
176+ argumentTypeCache . TryAdd ( propertyType , newInfo ) ;
177+
178+ return isArgument ;
149179 }
150180
151181 public static bool IsArgumentType ( Type propertyType ) => TypeHelper . AreTypesCompatible ( propertyType , argumentType ) ;
0 commit comments