@@ -129,5 +129,113 @@ public void StringAttributeValueRefEqualsStringEmpty () {
129129
130130            Assert . Same ( string . Empty ,  attr . NamedField ) ; 
131131        } 
132+ 
133+         [ AttributeUsage ( AttributeTargets . Parameter ) ] 
134+         internal  class  MyParameterAttribute  :  Attribute  { } 
135+ 
136+         [ AttributeUsage ( AttributeTargets . Property ) ] 
137+         internal  class  MyPropertyAttribute  :  Attribute  { } 
138+ 
139+         internal  sealed  class  PropertyAsParameterInfo  :  ParameterInfo 
140+         { 
141+             private  readonly  PropertyInfo  _underlyingProperty ; 
142+             private  readonly  ParameterInfo ?  _constructionParameterInfo ; 
143+ 
144+             public  PropertyAsParameterInfo ( PropertyInfo  property ,  ParameterInfo  parameterInfo ) 
145+             { 
146+                 _underlyingProperty  =  property ; 
147+                 _constructionParameterInfo  =  parameterInfo ; 
148+                 MemberImpl  =  _underlyingProperty ; 
149+             } 
150+ 
151+             public  override  object [ ]  GetCustomAttributes ( Type  attributeType ,  bool  inherit ) 
152+             { 
153+                 var  constructorAttributes  =  _constructionParameterInfo ? . GetCustomAttributes ( attributeType ,  inherit ) ; 
154+ 
155+                 if  ( constructorAttributes  ==  null  ||  constructorAttributes  is  {  Length :  0  } ) 
156+                 { 
157+                     return  _underlyingProperty . GetCustomAttributes ( attributeType ,  inherit ) ; 
158+                 } 
159+ 
160+                 var  propertyAttributes  =  _underlyingProperty . GetCustomAttributes ( attributeType ,  inherit ) ; 
161+ 
162+                 var  mergedAttributes  =  new  Attribute [ constructorAttributes . Length  +  propertyAttributes . Length ] ; 
163+                 Array . Copy ( constructorAttributes ,  mergedAttributes ,  constructorAttributes . Length ) ; 
164+                 Array . Copy ( propertyAttributes ,  0 ,  mergedAttributes ,  constructorAttributes . Length ,  propertyAttributes . Length ) ; 
165+ 
166+                 return  mergedAttributes ; 
167+             } 
168+ 
169+             public  override  object [ ]  GetCustomAttributes ( bool  inherit ) 
170+             { 
171+                 var  constructorAttributes  =  _constructionParameterInfo ? . GetCustomAttributes ( inherit ) ; 
172+ 
173+                 if  ( constructorAttributes  ==  null  ||  constructorAttributes  is  {  Length :  0  } ) 
174+                 { 
175+                     return  _underlyingProperty . GetCustomAttributes ( inherit ) ; 
176+                 } 
177+ 
178+                 var  propertyAttributes  =  _underlyingProperty . GetCustomAttributes ( inherit ) ; 
179+ 
180+                 var  mergedAttributes  =  new  object [ constructorAttributes . Length  +  propertyAttributes . Length ] ; 
181+                 Array . Copy ( constructorAttributes ,  mergedAttributes ,  constructorAttributes . Length ) ; 
182+                 Array . Copy ( propertyAttributes ,  0 ,  mergedAttributes ,  constructorAttributes . Length ,  propertyAttributes . Length ) ; 
183+ 
184+                 return  mergedAttributes ; 
185+             } 
186+ 
187+             public  override  IList < CustomAttributeData >  GetCustomAttributesData ( ) 
188+             { 
189+                 var  attributes  =  new  List < CustomAttributeData > ( 
190+                     _constructionParameterInfo ? . GetCustomAttributesData ( )  ??  Array . Empty < CustomAttributeData > ( ) ) ; 
191+                 attributes . AddRange ( _underlyingProperty . GetCustomAttributesData ( ) ) ; 
192+ 
193+                 return  attributes . AsReadOnly ( ) ; 
194+             } 
195+         } 
196+ 
197+         internal  class  CustomAttributeProviderTestClass 
198+         { 
199+             public  CustomAttributeProviderTestClass ( [ MyParameter ]  int  integerProperty ) 
200+             { 
201+                 IntegerProperty  =  integerProperty ; 
202+             } 
203+ 
204+             [ MyProperty ] 
205+             public  int  IntegerProperty  {  get ;  set ;  } 
206+         } 
207+ 
208+         [ Fact ] 
209+         public  void  CustomAttributeProvider  ( ) 
210+         { 
211+             var  type  =  typeof ( CustomAttributeProviderTestClass ) ; 
212+             var  propertyInfo  =  type . GetProperty ( nameof ( CustomAttributeProviderTestClass . IntegerProperty ) ) ; 
213+             var  ctorInfo  =  type . GetConstructor ( new  Type [ ]  {  typeof ( int )  } ) ; 
214+             var  ctorParamInfo  =  ctorInfo . GetParameters ( ) [ 0 ] ; 
215+             var  propertyAndParamInfo  =  new  PropertyAsParameterInfo ( propertyInfo ,  ctorParamInfo ) ; 
216+ 
217+             // check GetCustomAttribute API 
218+             var  cattrObjects  =  propertyAndParamInfo . GetCustomAttributes ( true ) ; 
219+             Assert . Equal ( 2 ,  cattrObjects . Length ) ; 
220+             Assert . Equal ( typeof ( MyParameterAttribute ) ,  cattrObjects [ 0 ] . GetType ( ) ) ; 
221+             Assert . Equal ( typeof ( MyPropertyAttribute ) ,  cattrObjects [ 1 ] . GetType ( ) ) ; 
222+ 
223+             cattrObjects  =  propertyAndParamInfo . GetCustomAttributes ( typeof ( Attribute ) ,  true ) ; 
224+             Assert . Equal ( 2 ,  cattrObjects . Length ) ; 
225+             Assert . Equal ( typeof ( MyParameterAttribute ) ,  cattrObjects [ 0 ] . GetType ( ) ) ; 
226+             Assert . Equal ( typeof ( MyPropertyAttribute ) ,  cattrObjects [ 1 ] . GetType ( ) ) ; 
227+ 
228+             var  cattrsEnumerable  =  propertyAndParamInfo . GetCustomAttributes ( ) ; 
229+             Attribute [ ]  cattrs  =  cattrsEnumerable . Cast < Attribute > ( ) . ToArray ( ) ; 
230+             Assert . Equal ( 2 ,  cattrs . Length ) ; 
231+             Assert . Equal ( typeof ( MyParameterAttribute ) ,  cattrs [ 0 ] . GetType ( ) ) ; 
232+             Assert . Equal ( typeof ( MyPropertyAttribute ) ,  cattrs [ 1 ] . GetType ( ) ) ; 
233+ 
234+             // check GetCustomAttributeData API 
235+             var  customAttributesData  =  propertyAndParamInfo . GetCustomAttributesData ( ) ; 
236+             Assert . Equal ( 2 ,  customAttributesData . Count ) ; 
237+             Assert . Equal ( typeof ( MyParameterAttribute ) ,  customAttributesData [ 0 ] . AttributeType ) ; 
238+             Assert . Equal ( typeof ( MyPropertyAttribute ) ,  customAttributesData [ 1 ] . AttributeType ) ; 
239+         } 
132240    } 
133241} 
0 commit comments