3 // Copyright (c) Microsoft Corporation. All rights reserved.
10 using System
.Reflection
;
11 using System
.Collections
.Generic
;
12 using System
.Runtime
.InteropServices
;
13 using System
.Globalization
;
14 using System
.Diagnostics
.Contracts
;
15 using System
.Security
;
16 using System
.Security
.Permissions
;
19 [AttributeUsageAttribute(AttributeTargets
.All
, Inherited
= true, AllowMultiple
=false)]
20 [ClassInterface(ClassInterfaceType
.None
)]
21 [ComDefaultInterface(typeof(_Attribute
))]
22 [System
.Runtime
.InteropServices
.ComVisible(true)]
23 public abstract partial class Attribute
: _Attribute
25 #region Private Statics
28 private static Attribute
[] InternalGetCustomAttributes(PropertyInfo element
, Type type
, bool inherit
)
30 Contract
.Requires(element
!= null);
31 Contract
.Requires(type
!= null);
32 Contract
.Requires(type
.IsSubclassOf(typeof(Attribute
)) || type
== typeof(Attribute
));
34 // walk up the hierarchy chain
35 Attribute
[] attributes
= (Attribute
[])element
.GetCustomAttributes(type
, inherit
);
40 // create the hashtable that keeps track of inherited types
41 Dictionary
<Type
, AttributeUsageAttribute
> types
= new Dictionary
<Type
, AttributeUsageAttribute
>(11);
43 // create an array list to collect all the requested attibutes
44 List
<Attribute
> attributeList
= new List
<Attribute
>();
45 CopyToArrayList(attributeList
, attributes
, types
);
47 PropertyInfo baseProp
= GetParentDefinition(element
);
48 while (baseProp
!= null)
50 attributes
= GetCustomAttributes(baseProp
, type
, false);
51 AddAttributesToList(attributeList
, attributes
, types
);
52 baseProp
= GetParentDefinition(baseProp
);
54 Array array
= CreateAttributeArrayHelper(type
, attributeList
.Count
);
55 Array
.Copy(attributeList
.ToArray(), 0, array
, 0, attributeList
.Count
);
56 return (Attribute
[])array
;
59 private static bool InternalIsDefined(PropertyInfo element
, Type attributeType
, bool inherit
)
61 // walk up the hierarchy chain
62 if (element
.IsDefined(attributeType
, inherit
))
67 AttributeUsageAttribute usage
= InternalGetAttributeUsage(attributeType
);
72 PropertyInfo baseProp
= GetParentDefinition(element
);
74 while (baseProp
!= null)
76 if (baseProp
.IsDefined(attributeType
, false))
79 baseProp
= GetParentDefinition(baseProp
);
86 private static PropertyInfo
GetParentDefinition(PropertyInfo property
)
88 Contract
.Requires(property
!= null);
90 // for the current property get the base class of the getter and the setter, they might be different
91 // note that this only works for RuntimeMethodInfo
92 MethodInfo propAccessor
= property
.GetGetMethod(true);
94 if (propAccessor
== null)
95 propAccessor
= property
.GetSetMethod(true);
97 RuntimeMethodInfo rtPropAccessor
= propAccessor
as RuntimeMethodInfo
;
99 if (rtPropAccessor
!= null)
101 rtPropAccessor
= rtPropAccessor
.GetParentDefinition();
103 if (rtPropAccessor
!= null)
105 #if FEATURE_LEGACYNETCF
106 // Mimicing NetCF which only looks for public properties.
107 if (CompatibilitySwitches
.IsAppEarlierThanWindowsPhone8
)
108 return rtPropAccessor
.DeclaringType
.GetProperty(property
.Name
, property
.PropertyType
);
109 #endif //FEATURE_LEGACYNETCF
111 // There is a public overload of Type.GetProperty that takes both a BingingFlags enum and a return type.
112 // However, we cannot use that because it doesn't accept null for "types".
113 return rtPropAccessor
.DeclaringType
.GetProperty(
115 BindingFlags
.Public
| BindingFlags
.NonPublic
| BindingFlags
.Instance
| BindingFlags
.DeclaredOnly
,
116 property
.PropertyType
);
126 private static Attribute
[] InternalGetCustomAttributes(EventInfo element
, Type type
, bool inherit
)
128 Contract
.Requires(element
!= null);
129 Contract
.Requires(type
!= null);
130 Contract
.Requires(type
.IsSubclassOf(typeof(Attribute
)) || type
== typeof(Attribute
));
132 // walk up the hierarchy chain
133 Attribute
[] attributes
= (Attribute
[])element
.GetCustomAttributes(type
, inherit
);
136 // create the hashtable that keeps track of inherited types
137 Dictionary
<Type
, AttributeUsageAttribute
> types
= new Dictionary
<Type
, AttributeUsageAttribute
>(11);
138 // create an array list to collect all the requested attibutes
139 List
<Attribute
> attributeList
= new List
<Attribute
>();
140 CopyToArrayList(attributeList
, attributes
, types
);
142 EventInfo baseEvent
= GetParentDefinition(element
);
143 while (baseEvent
!= null)
145 attributes
= GetCustomAttributes(baseEvent
, type
, false);
146 AddAttributesToList(attributeList
, attributes
, types
);
147 baseEvent
= GetParentDefinition(baseEvent
);
149 Array array
= CreateAttributeArrayHelper(type
, attributeList
.Count
);
150 Array
.Copy(attributeList
.ToArray(), 0, array
, 0, attributeList
.Count
);
151 return (Attribute
[])array
;
157 private static EventInfo
GetParentDefinition(EventInfo ev
)
159 Contract
.Requires(ev
!= null);
161 // note that this only works for RuntimeMethodInfo
162 MethodInfo
add = ev
.GetAddMethod(true);
164 RuntimeMethodInfo rtAdd
= add as RuntimeMethodInfo
;
168 rtAdd
= rtAdd
.GetParentDefinition();
170 return rtAdd
.DeclaringType
.GetEvent(ev
.Name
);
175 private static bool InternalIsDefined (EventInfo element
, Type attributeType
, bool inherit
)
177 Contract
.Requires(element
!= null);
179 // walk up the hierarchy chain
180 if (element
.IsDefined(attributeType
, inherit
))
185 AttributeUsageAttribute usage
= InternalGetAttributeUsage(attributeType
);
187 if (!usage
.Inherited
)
190 EventInfo baseEvent
= GetParentDefinition(element
);
192 while (baseEvent
!= null)
194 if (baseEvent
.IsDefined(attributeType
, false))
196 baseEvent
= GetParentDefinition(baseEvent
);
205 #region ParameterInfo
206 private static ParameterInfo
GetParentDefinition(ParameterInfo param
)
208 Contract
.Requires(param
!= null);
210 // note that this only works for RuntimeMethodInfo
211 RuntimeMethodInfo rtMethod
= param
.Member
as RuntimeMethodInfo
;
213 if (rtMethod
!= null)
215 rtMethod
= rtMethod
.GetParentDefinition();
217 if (rtMethod
!= null)
219 // Find the ParameterInfo on this method
220 ParameterInfo
[] parameters
= rtMethod
.GetParameters();
221 return parameters
[param
.Position
]; // Point to the correct ParameterInfo of the method
227 private static Attribute
[] InternalParamGetCustomAttributes(ParameterInfo param
, Type type
, bool inherit
)
229 Contract
.Requires(param
!= null);
231 // For ParameterInfo's we need to make sure that we chain through all the MethodInfo's in the inheritance chain that
232 // have this ParameterInfo defined. .We pick up all the CustomAttributes for the starting ParameterInfo. We need to pick up only attributes
233 // that are marked inherited from the remainder of the MethodInfo's in the inheritance chain.
234 // For MethodInfo's on an interface we do not do an inheritance walk so the default ParameterInfo attributes are returned.
235 // For MethodInfo's on a class we walk up the inheritance chain but do not look at the MethodInfo's on the interfaces that the
236 // class inherits from and return the respective ParameterInfo attributes
238 List
<Type
> disAllowMultiple
= new List
<Type
>();
242 type
= typeof(Attribute
);
244 objAttr
= param
.GetCustomAttributes(type
, false);
246 for (int i
=0;i
< objAttr
.Length
;i
++)
248 Type objType
= objAttr
[i
].GetType();
249 AttributeUsageAttribute attribUsage
= InternalGetAttributeUsage(objType
);
250 if (attribUsage
.AllowMultiple
== false)
251 disAllowMultiple
.Add(objType
);
254 // Get all the attributes that have Attribute as the base class
255 Attribute
[] ret
= null;
256 if (objAttr
.Length
== 0)
257 ret
= CreateAttributeArrayHelper(type
,0);
259 ret
= (Attribute
[])objAttr
;
261 if (param
.Member
.DeclaringType
== null) // This is an interface so we are done.
267 ParameterInfo baseParam
= GetParentDefinition(param
);
269 while (baseParam
!= null)
271 objAttr
= baseParam
.GetCustomAttributes(type
, false);
274 for (int i
=0;i
< objAttr
.Length
;i
++)
276 Type objType
= objAttr
[i
].GetType();
277 AttributeUsageAttribute attribUsage
= InternalGetAttributeUsage(objType
);
279 if ((attribUsage
.Inherited
) && (disAllowMultiple
.Contains(objType
) == false))
281 if (attribUsage
.AllowMultiple
== false)
282 disAllowMultiple
.Add(objType
);
289 // Get all the attributes that have Attribute as the base class
290 Attribute
[] attributes
= CreateAttributeArrayHelper(type
,count
);
293 for (int i
=0;i
< objAttr
.Length
;i
++)
295 if (objAttr
[i
] != null)
297 attributes
[count
] = (Attribute
)objAttr
[i
];
302 Attribute
[] temp
= ret
;
303 ret
= CreateAttributeArrayHelper(type
,temp
.Length
+ count
);
304 Array
.Copy(temp
,ret
,temp
.Length
);
306 int offset
= temp
.Length
;
308 for (int i
=0;i
< attributes
.Length
;i
++)
309 ret
[offset
+ i
] = attributes
[i
];
311 baseParam
= GetParentDefinition(baseParam
);
317 private static bool InternalParamIsDefined(ParameterInfo param
, Type type
, bool inherit
)
319 Contract
.Requires(param
!= null);
320 Contract
.Requires(type
!= null);
322 // For ParameterInfo's we need to make sure that we chain through all the MethodInfo's in the inheritance chain.
323 // We pick up all the CustomAttributes for the starting ParameterInfo. We need to pick up only attributes
324 // that are marked inherited from the remainder of the ParameterInfo's in the inheritance chain.
325 // For MethodInfo's on an interface we do not do an inheritance walk. For ParameterInfo's on a
326 // Class we walk up the inheritance chain but do not look at the MethodInfo's on the interfaces that the class inherits from.
328 if (param
.IsDefined(type
, false))
331 if (param
.Member
.DeclaringType
== null || !inherit
) // This is an interface so we are done.
334 ParameterInfo baseParam
= GetParentDefinition(param
);
336 while (baseParam
!= null)
338 Object
[] objAttr
= baseParam
.GetCustomAttributes(type
, false);
340 for (int i
=0; i
< objAttr
.Length
; i
++)
342 Type objType
= objAttr
[i
].GetType();
343 AttributeUsageAttribute attribUsage
= InternalGetAttributeUsage(objType
);
345 if ((objAttr
[i
] is Attribute
) && (attribUsage
.Inherited
))
349 baseParam
= GetParentDefinition(baseParam
);
358 private static void CopyToArrayList(List
<Attribute
> attributeList
,Attribute
[] attributes
,Dictionary
<Type
, AttributeUsageAttribute
> types
)
360 for (int i
= 0; i
< attributes
.Length
; i
++)
362 attributeList
.Add(attributes
[i
]);
364 Type attrType
= attributes
[i
].GetType();
366 if (!types
.ContainsKey(attrType
))
367 types
[attrType
] = InternalGetAttributeUsage(attrType
);
371 private static void AddAttributesToList(List
<Attribute
> attributeList
, Attribute
[] attributes
, Dictionary
<Type
, AttributeUsageAttribute
> types
)
373 for (int i
= 0; i
< attributes
.Length
; i
++)
375 Type attrType
= attributes
[i
].GetType();
376 AttributeUsageAttribute usage
= null;
377 types
.TryGetValue(attrType
, out usage
);
381 // the type has never been seen before if it's inheritable add it to the list
382 usage
= InternalGetAttributeUsage(attrType
);
383 types
[attrType
] = usage
;
386 attributeList
.Add(attributes
[i
]);
388 else if (usage
.Inherited
&& usage
.AllowMultiple
)
390 // we saw this type already add it only if it is inheritable and it does allow multiple
391 attributeList
.Add(attributes
[i
]);
396 private static AttributeUsageAttribute
InternalGetAttributeUsage(Type type
)
398 // Check if the custom attributes is Inheritable
399 Object
[] obj
= type
.GetCustomAttributes(typeof(AttributeUsageAttribute
), false);
402 return (AttributeUsageAttribute
)obj
[0];
405 return AttributeUsageAttribute
.Default
;
407 throw new FormatException(
408 Environment
.GetResourceString("Format_AttributeUsage", type
));
411 [System
.Security
.SecuritySafeCritical
]
412 private static Attribute
[] CreateAttributeArrayHelper(Type elementType
, int elementCount
)
414 return (Attribute
[])Array
.UnsafeCreateInstance(elementType
, elementCount
);
420 #region Public Statics
423 public static Attribute
[] GetCustomAttributes(MemberInfo element
, Type type
)
425 return GetCustomAttributes(element
, type
, true);
428 public static Attribute
[] GetCustomAttributes(MemberInfo element
, Type type
, bool inherit
)
431 throw new ArgumentNullException("element");
434 throw new ArgumentNullException("type");
436 if (!type
.IsSubclassOf(typeof(Attribute
)) && type
!= typeof(Attribute
))
437 throw new ArgumentException(Environment
.GetResourceString("Argument_MustHaveAttributeBaseClass"));
438 Contract
.EndContractBlock();
440 switch (element
.MemberType
)
442 case MemberTypes
.Property
:
443 return InternalGetCustomAttributes((PropertyInfo
)element
, type
, inherit
);
445 case MemberTypes
.Event
:
446 return InternalGetCustomAttributes((EventInfo
)element
, type
, inherit
);
449 return element
.GetCustomAttributes(type
, inherit
) as Attribute
[];
453 public static Attribute
[] GetCustomAttributes(MemberInfo element
)
455 return GetCustomAttributes(element
, true);
458 public static Attribute
[] GetCustomAttributes(MemberInfo element
, bool inherit
)
461 throw new ArgumentNullException("element");
462 Contract
.EndContractBlock();
464 switch (element
.MemberType
)
466 case MemberTypes
.Property
:
467 return InternalGetCustomAttributes((PropertyInfo
)element
, typeof(Attribute
), inherit
);
469 case MemberTypes
.Event
:
470 return InternalGetCustomAttributes((EventInfo
)element
, typeof(Attribute
), inherit
);
473 return element
.GetCustomAttributes(typeof(Attribute
), inherit
) as Attribute
[];
477 public static bool IsDefined(MemberInfo element
, Type attributeType
)
479 return IsDefined(element
, attributeType
, true);
482 public static bool IsDefined(MemberInfo element
, Type attributeType
, bool inherit
)
484 // Returns true if a custom attribute subclass of attributeType class/interface with inheritance walk
486 throw new ArgumentNullException("element");
488 if (attributeType
== null)
489 throw new ArgumentNullException("attributeType");
491 if (!attributeType
.IsSubclassOf(typeof(Attribute
)) && attributeType
!= typeof(Attribute
))
492 throw new ArgumentException(Environment
.GetResourceString("Argument_MustHaveAttributeBaseClass"));
493 Contract
.EndContractBlock();
495 switch(element
.MemberType
)
497 case MemberTypes
.Property
:
498 return InternalIsDefined((PropertyInfo
)element
, attributeType
, inherit
);
500 case MemberTypes
.Event
:
501 return InternalIsDefined((EventInfo
)element
, attributeType
, inherit
);
504 return element
.IsDefined(attributeType
, inherit
);
509 public static Attribute
GetCustomAttribute(MemberInfo element
, Type attributeType
)
511 return GetCustomAttribute(element
, attributeType
, true);
514 public static Attribute
GetCustomAttribute(MemberInfo element
, Type attributeType
, bool inherit
)
516 Attribute
[] attrib
= GetCustomAttributes(element
, attributeType
, inherit
);
518 if (attrib
== null || attrib
.Length
== 0)
521 if (attrib
.Length
== 1)
524 throw new AmbiguousMatchException(Environment
.GetResourceString("RFLCT.AmbigCust"));
529 #region ParameterInfo
530 public static Attribute
[] GetCustomAttributes(ParameterInfo element
)
532 return GetCustomAttributes(element
, true);
535 public static Attribute
[] GetCustomAttributes(ParameterInfo element
, Type attributeType
)
537 return (Attribute
[])GetCustomAttributes(element
, attributeType
, true);
540 public static Attribute
[] GetCustomAttributes(ParameterInfo element
, Type attributeType
, bool inherit
)
543 throw new ArgumentNullException("element");
545 if (attributeType
== null)
546 throw new ArgumentNullException("attributeType");
548 if (!attributeType
.IsSubclassOf(typeof(Attribute
)) && attributeType
!= typeof(Attribute
))
549 throw new ArgumentException(Environment
.GetResourceString("Argument_MustHaveAttributeBaseClass"));
551 if (element
.Member
== null)
552 throw new ArgumentException(Environment
.GetResourceString("Argument_InvalidParameterInfo"), "element");
554 Contract
.EndContractBlock();
556 MemberInfo member
= element
.Member
;
557 if (member
.MemberType
== MemberTypes
.Method
&& inherit
)
558 return InternalParamGetCustomAttributes(element
, attributeType
, inherit
) as Attribute
[];
560 return element
.GetCustomAttributes(attributeType
, inherit
) as Attribute
[];
563 public static Attribute
[] GetCustomAttributes(ParameterInfo element
, bool inherit
)
566 throw new ArgumentNullException("element");
568 if (element
.Member
== null)
569 throw new ArgumentException(Environment
.GetResourceString("Argument_InvalidParameterInfo"), "element");
571 Contract
.EndContractBlock();
573 MemberInfo member
= element
.Member
;
574 if (member
.MemberType
== MemberTypes
.Method
&& inherit
)
575 return InternalParamGetCustomAttributes(element
, null, inherit
) as Attribute
[];
577 return element
.GetCustomAttributes(typeof(Attribute
), inherit
) as Attribute
[];
580 public static bool IsDefined(ParameterInfo element
, Type attributeType
)
582 return IsDefined(element
, attributeType
, true);
585 public static bool IsDefined(ParameterInfo element
, Type attributeType
, bool inherit
)
587 // Returns true is a custom attribute subclass of attributeType class/interface with inheritance walk
589 throw new ArgumentNullException("element");
591 if (attributeType
== null)
592 throw new ArgumentNullException("attributeType");
594 if (!attributeType
.IsSubclassOf(typeof(Attribute
)) && attributeType
!= typeof(Attribute
))
595 throw new ArgumentException(Environment
.GetResourceString("Argument_MustHaveAttributeBaseClass"));
596 Contract
.EndContractBlock();
598 MemberInfo member
= element
.Member
;
600 switch(member
.MemberType
)
602 case MemberTypes
.Method
: // We need to climb up the member hierarchy
603 return InternalParamIsDefined(element
, attributeType
, inherit
);
605 case MemberTypes
.Constructor
:
606 return element
.IsDefined(attributeType
, false);
608 case MemberTypes
.Property
:
609 return element
.IsDefined(attributeType
, false);
612 Contract
.Assert(false, "Invalid type for ParameterInfo member in Attribute class");
613 throw new ArgumentException(Environment
.GetResourceString("Argument_InvalidParamInfo"));
617 public static Attribute
GetCustomAttribute(ParameterInfo element
, Type attributeType
)
619 return GetCustomAttribute(element
, attributeType
, true);
622 public static Attribute
GetCustomAttribute(ParameterInfo element
, Type attributeType
, bool inherit
)
624 // Returns an Attribute of base class/inteface attributeType on the ParameterInfo or null if none exists.
625 // throws an AmbiguousMatchException if there are more than one defined.
626 Attribute
[] attrib
= GetCustomAttributes(element
, attributeType
, inherit
);
628 if (attrib
== null || attrib
.Length
== 0)
631 if (attrib
.Length
== 0)
634 if (attrib
.Length
== 1)
637 throw new AmbiguousMatchException(Environment
.GetResourceString("RFLCT.AmbigCust"));
643 public static Attribute
[] GetCustomAttributes(Module element
, Type attributeType
)
645 return GetCustomAttributes (element
, attributeType
, true);
648 public static Attribute
[] GetCustomAttributes(Module element
)
650 return GetCustomAttributes(element
, true);
653 public static Attribute
[] GetCustomAttributes(Module element
, bool inherit
)
656 throw new ArgumentNullException("element");
657 Contract
.EndContractBlock();
659 return (Attribute
[])element
.GetCustomAttributes(typeof(Attribute
), inherit
);
662 public static Attribute
[] GetCustomAttributes(Module element
, Type attributeType
, bool inherit
)
665 throw new ArgumentNullException("element");
667 if (attributeType
== null)
668 throw new ArgumentNullException("attributeType");
670 if (!attributeType
.IsSubclassOf(typeof(Attribute
)) && attributeType
!= typeof(Attribute
))
671 throw new ArgumentException(Environment
.GetResourceString("Argument_MustHaveAttributeBaseClass"));
672 Contract
.EndContractBlock();
674 return (Attribute
[])element
.GetCustomAttributes(attributeType
, inherit
);
677 public static bool IsDefined(Module element
, Type attributeType
)
679 return IsDefined(element
, attributeType
, false);
682 public static bool IsDefined(Module element
, Type attributeType
, bool inherit
)
684 // Returns true is a custom attribute subclass of attributeType class/interface with no inheritance walk
686 throw new ArgumentNullException("element");
688 if (attributeType
== null)
689 throw new ArgumentNullException("attributeType");
691 if (!attributeType
.IsSubclassOf(typeof(Attribute
)) && attributeType
!= typeof(Attribute
))
692 throw new ArgumentException(Environment
.GetResourceString("Argument_MustHaveAttributeBaseClass"));
693 Contract
.EndContractBlock();
695 return element
.IsDefined(attributeType
,false);
698 public static Attribute
GetCustomAttribute(Module element
, Type attributeType
)
700 return GetCustomAttribute(element
, attributeType
, true);
703 public static Attribute
GetCustomAttribute(Module element
, Type attributeType
, bool inherit
)
705 // Returns an Attribute of base class/inteface attributeType on the Module or null if none exists.
706 // throws an AmbiguousMatchException if there are more than one defined.
707 Attribute
[] attrib
= GetCustomAttributes(element
,attributeType
,inherit
);
709 if (attrib
== null || attrib
.Length
== 0)
712 if (attrib
.Length
== 1)
715 throw new AmbiguousMatchException(Environment
.GetResourceString("RFLCT.AmbigCust"));
721 public static Attribute
[] GetCustomAttributes(Assembly element
, Type attributeType
)
723 return GetCustomAttributes(element
, attributeType
, true);
726 public static Attribute
[] GetCustomAttributes(Assembly element
, Type attributeType
, bool inherit
)
729 throw new ArgumentNullException("element");
731 if (attributeType
== null)
732 throw new ArgumentNullException("attributeType");
734 if (!attributeType
.IsSubclassOf(typeof(Attribute
)) && attributeType
!= typeof(Attribute
))
735 throw new ArgumentException(Environment
.GetResourceString("Argument_MustHaveAttributeBaseClass"));
736 Contract
.EndContractBlock();
738 return (Attribute
[])element
.GetCustomAttributes(attributeType
, inherit
);
741 public static Attribute
[] GetCustomAttributes(Assembly element
)
743 return GetCustomAttributes(element
, true);
746 public static Attribute
[] GetCustomAttributes(Assembly element
, bool inherit
)
749 throw new ArgumentNullException("element");
750 Contract
.EndContractBlock();
752 return (Attribute
[])element
.GetCustomAttributes(typeof(Attribute
), inherit
);
755 public static bool IsDefined (Assembly element
, Type attributeType
)
757 return IsDefined (element
, attributeType
, true);
760 public static bool IsDefined (Assembly element
, Type attributeType
, bool inherit
)
762 // Returns true is a custom attribute subclass of attributeType class/interface with no inheritance walk
764 throw new ArgumentNullException("element");
766 if (attributeType
== null)
767 throw new ArgumentNullException("attributeType");
769 if (!attributeType
.IsSubclassOf(typeof(Attribute
)) && attributeType
!= typeof(Attribute
))
770 throw new ArgumentException(Environment
.GetResourceString("Argument_MustHaveAttributeBaseClass"));
771 Contract
.EndContractBlock();
773 return element
.IsDefined(attributeType
, false);
776 public static Attribute
GetCustomAttribute(Assembly element
, Type attributeType
)
778 return GetCustomAttribute (element
, attributeType
, true);
781 public static Attribute
GetCustomAttribute(Assembly element
, Type attributeType
, bool inherit
)
783 // Returns an Attribute of base class/inteface attributeType on the Assembly or null if none exists.
784 // throws an AmbiguousMatchException if there are more than one defined.
785 Attribute
[] attrib
= GetCustomAttributes(element
,attributeType
,inherit
);
787 if (attrib
== null || attrib
.Length
== 0)
790 if (attrib
.Length
== 1)
793 throw new AmbiguousMatchException(Environment
.GetResourceString("RFLCT.AmbigCust"));
801 protected Attribute() { }
804 #region Object Overrides
805 [SecuritySafeCritical
]
806 public override bool Equals(Object obj
)
811 RuntimeType thisType
= (RuntimeType
)this.GetType();
812 RuntimeType thatType
= (RuntimeType
)obj
.GetType();
814 if (thatType
!= thisType
)
817 Object thisObj
= this;
818 Object thisResult
, thatResult
;
820 FieldInfo
[] thisFields
= thisType
.GetFields(BindingFlags
.Instance
| BindingFlags
.Public
| BindingFlags
.NonPublic
);
822 for (int i
= 0; i
< thisFields
.Length
; i
++)
824 // Visibility check and consistency check are not necessary.
825 thisResult
= ((RtFieldInfo
)thisFields
[i
]).UnsafeGetValue(thisObj
);
826 thatResult
= ((RtFieldInfo
)thisFields
[i
]).UnsafeGetValue(obj
);
828 if (!AreFieldValuesEqual(thisResult
, thatResult
))
837 // Compares values of custom-attribute fields.
838 private static bool AreFieldValuesEqual(Object thisValue
, Object thatValue
)
840 if (thisValue
== null && thatValue
== null)
842 if (thisValue
== null || thatValue
== null)
845 if (thisValue
.GetType().IsArray
)
847 // Ensure both are arrays of the same type.
848 if (!thisValue
.GetType().Equals(thatValue
.GetType()))
853 Array thisValueArray
= thisValue
as Array
;
854 Array thatValueArray
= thatValue
as Array
;
855 if (thisValueArray
.Length
!= thatValueArray
.Length
)
860 // Attributes can only contain single-dimension arrays, so we don't need to worry about
861 // multidimensional arrays.
862 Contract
.Assert(thisValueArray
.Rank
== 1 && thatValueArray
.Rank
== 1);
863 for (int j
= 0; j
< thisValueArray
.Length
; j
++)
865 if (!AreFieldValuesEqual(thisValueArray
.GetValue(j
), thatValueArray
.GetValue(j
)))
873 // An object of type Attribute will cause a stack overflow.
874 // However, this should never happen because custom attributes cannot contain values other than
875 // constants, single-dimensional arrays and typeof expressions.
876 Contract
.Assert(!(thisValue
is Attribute
));
877 if (!thisValue
.Equals(thatValue
))
884 [SecuritySafeCritical
]
885 public override int GetHashCode()
887 Type type
= GetType();
889 FieldInfo
[] fields
= type
.GetFields(BindingFlags
.Instance
| BindingFlags
.Public
| BindingFlags
.NonPublic
);
892 for (int i
= 0; i
< fields
.Length
; i
++)
894 // Visibility check and consistency check are not necessary.
895 Object fieldValue
= ((RtFieldInfo
)fields
[i
]).UnsafeGetValue(this);
897 // The hashcode of an array ignores the contents of the array, so it can produce
898 // different hashcodes for arrays with the same contents.
899 // Since we do deep comparisons of arrays in Equals(), this means Equals and GetHashCode will
900 // be inconsistent for arrays. Therefore, we ignore hashes of arrays.
901 if (fieldValue
!= null && !fieldValue
.GetType().IsArray
)
909 return vThis
.GetHashCode();
911 return type
.GetHashCode();
915 #region Public Virtual Members
916 public virtual Object TypeId { get { return GetType(); }
}
918 public virtual bool Match(Object obj
) { return Equals(obj); }
921 #region Public Members
922 public virtual bool IsDefaultAttribute() { return false; }
925 void _Attribute
.GetTypeInfoCount(out uint pcTInfo
)
927 throw new NotImplementedException();
930 void _Attribute
.GetTypeInfo(uint iTInfo
, uint lcid
, IntPtr ppTInfo
)
932 throw new NotImplementedException();
935 void _Attribute
.GetIDsOfNames([In
] ref Guid riid
, IntPtr rgszNames
, uint cNames
, uint lcid
, IntPtr rgDispId
)
937 throw new NotImplementedException();
940 void _Attribute
.Invoke(uint dispIdMember
, [In
] ref Guid riid
, uint lcid
, short wFlags
, IntPtr pDispParams
, IntPtr pVarResult
, IntPtr pExcepInfo
, IntPtr puArgErr
)
942 throw new NotImplementedException();