The Labs \ Source Viewer \ SSCLI \ System \ Attribute

  1. // ==++==
  2. //
  3. //
  4. // Copyright (c) 2006 Microsoft Corporation. All rights reserved.
  5. //
  6. // The use and distribution terms for this software are contained in the file
  7. // named license.txt, which can be found in the root of this distribution.
  8. // By using this software in any fashion, you are agreeing to be bound by the
  9. // terms of this license.
  10. //
  11. // You must not remove this notice, or any other, from this software.
  12. //
  13. //
  14. // ==--==
  15. namespace System
  16. {
  17.    
  18.     using System;
  19.     using System.Reflection;
  20.     using System.Collections;
  21.     using System.Runtime.InteropServices;
  22.     using System.Globalization;
  23.    
  24.     [Serializable(), AttributeUsageAttribute(AttributeTargets.All, Inherited = true, AllowMultiple = false)]
  25.     [ClassInterface(ClassInterfaceType.None)]
  26.     [ComDefaultInterface(typeof(_Attribute))]
  27.     [System.Runtime.InteropServices.ComVisible(true)]
  28.     public abstract class Attribute : _Attribute
  29.     {
  30.         #region Private Statics
  31.        
  32.         #region PropertyInfo
  33.         private static Attribute[] InternalGetCustomAttributes(PropertyInfo element, Type type, bool inherit)
  34.         {
  35.             // walk up the hierarchy chain
  36.             Attribute[] attributes = (Attribute[])element.GetCustomAttributes(type, inherit);
  37.            
  38.             if (!inherit)
  39.                 return attributes;
  40.            
  41.             // create the hashtable that keeps track of inherited types
  42.             Hashtable types = new Hashtable(11);
  43.            
  44.             // create an array list to collect all the requested attibutes
  45.             ArrayList attributeList = new ArrayList();
  46.             CopyToArrayList(attributeList, attributes, types);
  47.            
  48.             PropertyInfo baseProp = GetParentDefinition(element);
  49.             while (baseProp != null) {
  50.                 attributes = GetCustomAttributes(baseProp, type, false);
  51.                 AddAttributesToList(attributeList, attributes, types);
  52.                 baseProp = GetParentDefinition(baseProp);
  53.             }
  54.             return (Attribute[])attributeList.ToArray(type);
  55.         }
  56.        
  57.         private static bool InternalIsDefined(PropertyInfo element, Type attributeType, bool inherit)
  58.         {
  59.             // walk up the hierarchy chain
  60.             if (element.IsDefined(attributeType, inherit))
  61.                 return true;
  62.            
  63.             if (inherit) {
  64.                 AttributeUsageAttribute usage = InternalGetAttributeUsage(attributeType);
  65.                
  66.                 if (!usage.Inherited)
  67.                     return false;
  68.                
  69.                 PropertyInfo baseProp = GetParentDefinition(element);
  70.                
  71.                 while (baseProp != null) {
  72.                     if (baseProp.IsDefined(attributeType, false))
  73.                         return true;
  74.                    
  75.                     baseProp = GetParentDefinition(baseProp);
  76.                 }
  77.             }
  78.            
  79.             return false;
  80.         }
  81.        
  82.         private static PropertyInfo GetParentDefinition(PropertyInfo property)
  83.         {
  84.             // for the current property get the base class of the getter and the setter, they might be different
  85.             MethodInfo propAccessor = property.GetGetMethod(true);
  86.            
  87.             if (propAccessor == null)
  88.                 propAccessor = property.GetSetMethod(true);
  89.            
  90.             if (propAccessor != null) {
  91.                 propAccessor = propAccessor.GetParentDefinition();
  92.                
  93.                 if (propAccessor != null)
  94.                     return propAccessor.DeclaringType.GetProperty(property.Name, property.PropertyType);
  95.             }
  96.            
  97.             return null;
  98.         }
  99.        
  100.         #endregion
  101.        
  102.         #region EventInfo
  103.         private static Attribute[] InternalGetCustomAttributes(EventInfo element, Type type, bool inherit)
  104.         {
  105.             // walk up the hierarchy chain
  106.             Attribute[] attributes = (Attribute[])element.GetCustomAttributes(type, inherit);
  107.             if (inherit) {
  108.                 // create the hashtable that keeps track of inherited types
  109.                 Hashtable types = new Hashtable(11);
  110.                 // create an array list to collect all the requested attibutes
  111.                 ArrayList attributeList = new ArrayList();
  112.                 CopyToArrayList(attributeList, attributes, types);
  113.                
  114.                 EventInfo baseEvent = GetParentDefinition(element);
  115.                 while (baseEvent != null) {
  116.                     attributes = GetCustomAttributes(baseEvent, type, false);
  117.                     AddAttributesToList(attributeList, attributes, types);
  118.                     baseEvent = GetParentDefinition(baseEvent);
  119.                 }
  120.                 return (Attribute[])attributeList.ToArray(type);
  121.             }
  122.             else
  123.                 return attributes;
  124.         }
  125.         private static EventInfo GetParentDefinition(EventInfo ev)
  126.         {
  127.             MethodInfo add = ev.GetAddMethod(true);
  128.             if (add != null) {
  129.                 add = add.GetParentDefinition();
  130.                 if (add != null)
  131.                     return add.DeclaringType.GetEvent(ev.Name);
  132.             }
  133.             return null;
  134.         }
  135.        
  136.         private static bool InternalIsDefined(EventInfo element, Type attributeType, bool inherit)
  137.         {
  138.             // walk up the hierarchy chain
  139.             if (element.IsDefined(attributeType, inherit))
  140.                 return true;
  141.            
  142.             if (inherit) {
  143.                 AttributeUsageAttribute usage = InternalGetAttributeUsage(attributeType);
  144.                
  145.                 if (!usage.Inherited)
  146.                     return false;
  147.                
  148.                 EventInfo baseEvent = GetParentDefinition(element);
  149.                
  150.                 while (baseEvent != null) {
  151.                     if (baseEvent.IsDefined(attributeType, false))
  152.                         return true;
  153.                     baseEvent = GetParentDefinition(baseEvent);
  154.                 }
  155.             }
  156.            
  157.             return false;
  158.         }
  159.        
  160.         #endregion
  161.        
  162.         #region ParameterInfo
  163.         private static Attribute[] InternalParamGetCustomAttributes(MethodInfo method, ParameterInfo param, Type type, bool inherit)
  164.         {
  165.             // For ParameterInfo's we need to make sure that we chain through all the MethodInfo's in the inheritance chain that
  166.             // have this ParameterInfo defined. .We pick up all the CustomAttributes for the starting ParameterInfo. We need to pick up only attributes
  167.             // that are marked inherited from the remainder of the MethodInfo's in the inheritance chain.
  168.             // For MethodInfo's on an interface we do not do an inheritance walk so the default ParameterInfo attributes are returned.
  169.             // 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
  170.             // class inherits from and return the respective ParameterInfo attributes
  171.            
  172.             ArrayList disAllowMultiple = new ArrayList();
  173.             object[] objAttr;
  174.            
  175.             if (type == null)
  176.                 type = typeof(Attribute);
  177.            
  178.             objAttr = param.GetCustomAttributes(type, false);
  179.            
  180.             for (int i = 0; i < objAttr.Length; i++) {
  181.                 Type objType = objAttr[i].GetType();
  182.                 AttributeUsageAttribute attribUsage = InternalGetAttributeUsage(objType);
  183.                 if (attribUsage.AllowMultiple == false)
  184.                     disAllowMultiple.Add(objType);
  185.             }
  186.            
  187.             // Get all the attributes that have Attribute as the base class
  188.             Attribute[] ret = null;
  189.             if (objAttr.Length == 0)
  190.                 ret = (Attribute[])Array.CreateInstance(type, 0);
  191.             else
  192.                 ret = (Attribute[])objAttr;
  193.            
  194.             if (method.DeclaringType == null)
  195.                 // This is an interface so we are done.
  196.                 return ret;
  197.            
  198.             if (!inherit)
  199.                 return ret;
  200.            
  201.             int paramPosition = param.Position;
  202.             method = method.GetParentDefinition();
  203.            
  204.             while (method != null) {
  205.                 // Find the ParameterInfo on this method
  206.                 ParameterInfo[] parameters = method.GetParameters();
  207.                 param = parameters[paramPosition];
  208.                 // Point to the correct ParameterInfo of the method
  209.                 objAttr = param.GetCustomAttributes(type, false);
  210.                
  211.                 int count = 0;
  212.                 for (int i = 0; i < objAttr.Length; i++) {
  213.                     Type objType = objAttr[i].GetType();
  214.                     AttributeUsageAttribute attribUsage = InternalGetAttributeUsage(objType);
  215.                    
  216.                     if ((attribUsage.Inherited) && (disAllowMultiple.Contains(objType) == false)) {
  217.                         if (attribUsage.AllowMultiple == false)
  218.                             disAllowMultiple.Add(objType);
  219.                         count++;
  220.                     }
  221.                     else
  222.                         objAttr[i] = null;
  223.                 }
  224.                
  225.                 // Get all the attributes that have Attribute as the base class
  226.                 Attribute[] attributes = (Attribute[])Array.CreateInstance(type, count);
  227.                
  228.                 count = 0;
  229.                 for (int i = 0; i < objAttr.Length; i++) {
  230.                     if (objAttr[i] != null) {
  231.                         attributes[count] = (Attribute)objAttr[i];
  232.                         count++;
  233.                     }
  234.                 }
  235.                
  236.                 Attribute[] temp = ret;
  237.                 ret = (Attribute[])Array.CreateInstance(type, temp.Length + count);
  238.                 Array.Copy(temp, ret, temp.Length);
  239.                
  240.                 int offset = temp.Length;
  241.                
  242.                 for (int i = 0; i < attributes.Length; i++)
  243.                     ret[offset + i] = attributes[i];
  244.                
  245.                 method = method.GetParentDefinition();
  246.                
  247.             }
  248.            
  249.             return ret;
  250.            
  251.         }
  252.        
  253.         private static bool InternalParamIsDefined(MethodInfo method, ParameterInfo param, Type type, bool inherit)
  254.         {
  255.             // For ParameterInfo's we need to make sure that we chain through all the MethodInfo's in the inheritance chain.
  256.             // We pick up all the CustomAttributes for the starting ParameterInfo. We need to pick up only attributes
  257.             // that are marked inherited from the remainder of the ParameterInfo's in the inheritance chain.
  258.             // For MethodInfo's on an interface we do not do an inheritance walk. For ParameterInfo's on a
  259.             // Class we walk up the inheritance chain but do not look at the MethodInfo's on the interfaces that the class inherits from.
  260.            
  261.             if (param.IsDefined(type, false))
  262.                 return true;
  263.            
  264.             if (method.DeclaringType == null || !inherit)
  265.                 // This is an interface so we are done.
  266.                 return false;
  267.            
  268.             int paramPosition = param.Position;
  269.             method = method.GetParentDefinition();
  270.            
  271.             while (method != null) {
  272.                 ParameterInfo[] parameters = method.GetParameters();
  273.                 param = parameters[paramPosition];
  274.                
  275.                 object[] objAttr = param.GetCustomAttributes(type, false);
  276.                
  277.                 for (int i = 0; i < objAttr.Length; i++) {
  278.                     Type objType = objAttr[i].GetType();
  279.                     AttributeUsageAttribute attribUsage = InternalGetAttributeUsage(objType);
  280.                    
  281.                     if ((objAttr[i] is Attribute) && (attribUsage.Inherited))
  282.                         return true;
  283.                 }
  284.                
  285.                 method = method.GetParentDefinition();
  286.             }
  287.            
  288.             return false;
  289.         }
  290.        
  291.         #endregion
  292.        
  293.         #region Utility
  294.         private static void CopyToArrayList(ArrayList attributeList, Attribute[] attributes, Hashtable types)
  295.         {
  296.             for (int i = 0; i < attributes.Length; i++) {
  297.                 attributeList.Add(attributes[i]);
  298.                
  299.                 Type attrType = attributes[i].GetType();
  300.                
  301.                 if (!types.Contains(attrType))
  302.                     types[attrType] = InternalGetAttributeUsage(attrType);
  303.             }
  304.         }
  305.        
  306.         private static void AddAttributesToList(ArrayList attributeList, Attribute[] attributes, Hashtable types)
  307.         {
  308.             for (int i = 0; i < attributes.Length; i++) {
  309.                 Type attrType = attributes[i].GetType();
  310.                 AttributeUsageAttribute usage = (AttributeUsageAttribute)types[attrType];
  311.                
  312.                 if (usage == null) {
  313.                     // the type has never been seen before if it's inheritable add it to the list
  314.                     usage = InternalGetAttributeUsage(attrType);
  315.                     types[attrType] = usage;
  316.                    
  317.                     if (usage.Inherited)
  318.                         attributeList.Add(attributes[i]);
  319.                 }
  320.                 else if (usage.Inherited && usage.AllowMultiple) {
  321.                     // we saw this type already add it only if it is inheritable and it does allow multiple
  322.                     attributeList.Add(attributes[i]);
  323.                 }
  324.             }
  325.         }
  326.        
  327.         private static AttributeUsageAttribute InternalGetAttributeUsage(Type type)
  328.         {
  329.             // Check if the custom attributes is Inheritable
  330.             object[] obj = type.GetCustomAttributes(typeof(AttributeUsageAttribute), false);
  331.            
  332.             if (obj.Length == 1)
  333.                 return (AttributeUsageAttribute)obj[0];
  334.            
  335.             if (obj.Length == 0)
  336.                 return AttributeUsageAttribute.Default;
  337.            
  338.             throw new FormatException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Format_AttributeUsage"), type));
  339.         }
  340.        
  341.         #endregion
  342.        
  343.         #endregion
  344.        
  345.         #region Public Statics
  346.        
  347.         #region MemberInfo
  348.         public static Attribute[] GetCustomAttributes(MemberInfo element, Type type)
  349.         {
  350.             return GetCustomAttributes(element, type, true);
  351.         }
  352.        
  353.         public static Attribute[] GetCustomAttributes(MemberInfo element, Type type, bool inherit)
  354.         {
  355.             if (element == null)
  356.                 throw new ArgumentNullException("element");
  357.            
  358.             if (type == null)
  359.                 throw new ArgumentNullException("type");
  360.            
  361.             if (!type.IsSubclassOf(typeof(Attribute)) && type != typeof(Attribute))
  362.                 throw new ArgumentException(Environment.GetResourceString("Argument_MustHaveAttributeBaseClass"));
  363.            
  364.             switch (element.MemberType) {
  365.                 case MemberTypes.Property:
  366.                     return InternalGetCustomAttributes((PropertyInfo)element, type, inherit);
  367.                 case MemberTypes.Event:
  368.                    
  369.                     return InternalGetCustomAttributes((EventInfo)element, type, inherit);
  370.                 default:
  371.                    
  372.                     return element.GetCustomAttributes(type, inherit) as Attribute[];
  373.             }
  374.         }
  375.        
  376.         public static Attribute[] GetCustomAttributes(MemberInfo element)
  377.         {
  378.             return GetCustomAttributes(element, true);
  379.         }
  380.        
  381.         public static Attribute[] GetCustomAttributes(MemberInfo element, bool inherit)
  382.         {
  383.             if (element == null)
  384.                 throw new ArgumentNullException("element");
  385.            
  386.             switch (element.MemberType) {
  387.                 case MemberTypes.Property:
  388.                     return InternalGetCustomAttributes((PropertyInfo)element, typeof(Attribute), inherit);
  389.                 case MemberTypes.Event:
  390.                    
  391.                     return InternalGetCustomAttributes((EventInfo)element, typeof(Attribute), inherit);
  392.                 default:
  393.                    
  394.                     return element.GetCustomAttributes(typeof(Attribute), inherit) as Attribute[];
  395.             }
  396.         }
  397.        
  398.         public static bool IsDefined(MemberInfo element, Type attributeType)
  399.         {
  400.             return IsDefined(element, attributeType, true);
  401.         }
  402.        
  403.         public static bool IsDefined(MemberInfo element, Type attributeType, bool inherit)
  404.         {
  405.             // Returns true if a custom attribute subclass of attributeType class/interface with inheritance walk
  406.             if (element == null)
  407.                 throw new ArgumentNullException("element");
  408.            
  409.             if (attributeType == null)
  410.                 throw new ArgumentNullException("attributeType");
  411.            
  412.             if (!attributeType.IsSubclassOf(typeof(Attribute)) && attributeType != typeof(Attribute))
  413.                 throw new ArgumentException(Environment.GetResourceString("Argument_MustHaveAttributeBaseClass"));
  414.            
  415.             switch (element.MemberType) {
  416.                 case MemberTypes.Property:
  417.                     return InternalIsDefined((PropertyInfo)element, attributeType, inherit);
  418.                 case MemberTypes.Event:
  419.                    
  420.                     return InternalIsDefined((EventInfo)element, attributeType, inherit);
  421.                 default:
  422.                    
  423.                     return element.IsDefined(attributeType, inherit);
  424.             }
  425.            
  426.         }
  427.        
  428.         public static Attribute GetCustomAttribute(MemberInfo element, Type attributeType)
  429.         {
  430.             return GetCustomAttribute(element, attributeType, true);
  431.         }
  432.        
  433.         public static Attribute GetCustomAttribute(MemberInfo element, Type attributeType, bool inherit)
  434.         {
  435.             Attribute[] attrib = GetCustomAttributes(element, attributeType, inherit);
  436.            
  437.             if (attrib == null || attrib.Length == 0)
  438.                 return null;
  439.            
  440.             if (attrib.Length == 1)
  441.                 return attrib[0];
  442.            
  443.             throw new AmbiguousMatchException(Environment.GetResourceString("RFLCT.AmbigCust"));
  444.         }
  445.        
  446.         #endregion
  447.        
  448.         #region ParameterInfo
  449.         public static Attribute[] GetCustomAttributes(ParameterInfo element)
  450.         {
  451.             return GetCustomAttributes(element, true);
  452.         }
  453.        
  454.         public static Attribute[] GetCustomAttributes(ParameterInfo element, Type attributeType)
  455.         {
  456.             return (Attribute[])GetCustomAttributes(element, attributeType, true);
  457.         }
  458.        
  459.         public static Attribute[] GetCustomAttributes(ParameterInfo element, Type attributeType, bool inherit)
  460.         {
  461.             if (element == null)
  462.                 throw new ArgumentNullException("element");
  463.            
  464.             if (attributeType == null)
  465.                 throw new ArgumentNullException("attributeType");
  466.            
  467.             if (!attributeType.IsSubclassOf(typeof(Attribute)) && attributeType != typeof(Attribute))
  468.                 throw new ArgumentException(Environment.GetResourceString("Argument_MustHaveAttributeBaseClass"));
  469.            
  470.             MemberInfo member = element.Member;
  471.            
  472.             if (member.MemberType == MemberTypes.Method && inherit)
  473.                 return InternalParamGetCustomAttributes((MethodInfo)member, element, attributeType, inherit) as Attribute[];
  474.            
  475.             return element.GetCustomAttributes(attributeType, inherit) as Attribute[];
  476.         }
  477.        
  478.         public static Attribute[] GetCustomAttributes(ParameterInfo element, bool inherit)
  479.         {
  480.             if (element == null)
  481.                 throw new ArgumentNullException("element");
  482.            
  483.             MemberInfo member = element.Member;
  484.            
  485.             if (member.MemberType == MemberTypes.Method && inherit)
  486.                 return InternalParamGetCustomAttributes((MethodInfo)member, element, null, inherit) as Attribute[];
  487.            
  488.             return element.GetCustomAttributes(typeof(Attribute), inherit) as Attribute[];
  489.         }
  490.        
  491.         public static bool IsDefined(ParameterInfo element, Type attributeType)
  492.         {
  493.             return IsDefined(element, attributeType, true);
  494.         }
  495.        
  496.         public static bool IsDefined(ParameterInfo element, Type attributeType, bool inherit)
  497.         {
  498.             // Returns true is a custom attribute subclass of attributeType class/interface with inheritance walk
  499.             if (element == null)
  500.                 throw new ArgumentNullException("element");
  501.            
  502.             if (attributeType == null)
  503.                 throw new ArgumentNullException("attributeType");
  504.            
  505.             if (!attributeType.IsSubclassOf(typeof(Attribute)) && attributeType != typeof(Attribute))
  506.                 throw new ArgumentException(Environment.GetResourceString("Argument_MustHaveAttributeBaseClass"));
  507.            
  508.             MemberInfo member = element.Member;
  509.            
  510.             switch (member.MemberType) {
  511.                 case MemberTypes.Method:
  512.                     // We need to climb up the member hierarchy
  513.                     return InternalParamIsDefined((MethodInfo)member, element, attributeType, inherit);
  514.                 case MemberTypes.Constructor:
  515.                    
  516.                     return element.IsDefined(attributeType, false);
  517.                 case MemberTypes.Property:
  518.                    
  519.                     return element.IsDefined(attributeType, false);
  520.                 default:
  521.                    
  522.                     BCLDebug.Assert(false, "Invalid type for ParameterInfo member in Attribute class");
  523.                     throw new ArgumentException(Environment.GetResourceString("Argument_InvalidParamInfo"));
  524.                     break;
  525.             }
  526.         }
  527.        
  528.         public static Attribute GetCustomAttribute(ParameterInfo element, Type attributeType)
  529.         {
  530.             return GetCustomAttribute(element, attributeType, true);
  531.         }
  532.        
  533.         public static Attribute GetCustomAttribute(ParameterInfo element, Type attributeType, bool inherit)
  534.         {
  535.             // Returns an Attribute of base class/inteface attributeType on the ParameterInfo or null if none exists.
  536.             // throws an AmbiguousMatchException if there are more than one defined.
  537.             Attribute[] attrib = GetCustomAttributes(element, attributeType, inherit);
  538.            
  539.             if (attrib == null || attrib.Length == 0)
  540.                 return null;
  541.            
  542.             if (attrib.Length == 0)
  543.                 return null;
  544.            
  545.             if (attrib.Length == 1)
  546.                 return attrib[0];
  547.            
  548.             throw new AmbiguousMatchException(Environment.GetResourceString("RFLCT.AmbigCust"));
  549.         }
  550.        
  551.         #endregion
  552.        
  553.         #region Module
  554.         public static Attribute[] GetCustomAttributes(Module element, Type attributeType)
  555.         {
  556.             return GetCustomAttributes(element, attributeType, true);
  557.         }
  558.        
  559.         public static Attribute[] GetCustomAttributes(Module element)
  560.         {
  561.             return GetCustomAttributes(element, true);
  562.         }
  563.        
  564.         public static Attribute[] GetCustomAttributes(Module element, bool inherit)
  565.         {
  566.             if (element == null)
  567.                 throw new ArgumentNullException("element");
  568.            
  569.             return (Attribute[])element.GetCustomAttributes(typeof(Attribute), inherit);
  570.         }
  571.        
  572.         public static Attribute[] GetCustomAttributes(Module element, Type attributeType, bool inherit)
  573.         {
  574.             if (element == null)
  575.                 throw new ArgumentNullException("element");
  576.            
  577.             if (attributeType == null)
  578.                 throw new ArgumentNullException("attributeType");
  579.            
  580.             if (!attributeType.IsSubclassOf(typeof(Attribute)) && attributeType != typeof(Attribute))
  581.                 throw new ArgumentException(Environment.GetResourceString("Argument_MustHaveAttributeBaseClass"));
  582.            
  583.             return (Attribute[])element.GetCustomAttributes(attributeType, inherit);
  584.         }
  585.        
  586.         public static bool IsDefined(Module element, Type attributeType)
  587.         {
  588.             return IsDefined(element, attributeType, false);
  589.         }
  590.        
  591.         public static bool IsDefined(Module element, Type attributeType, bool inherit)
  592.         {
  593.             // Returns true is a custom attribute subclass of attributeType class/interface with no inheritance walk
  594.             if (element == null)
  595.                 throw new ArgumentNullException("element");
  596.            
  597.             if (attributeType == null)
  598.                 throw new ArgumentNullException("attributeType");
  599.            
  600.             if (!attributeType.IsSubclassOf(typeof(Attribute)) && attributeType != typeof(Attribute))
  601.                 throw new ArgumentException(Environment.GetResourceString("Argument_MustHaveAttributeBaseClass"));
  602.            
  603.             return element.IsDefined(attributeType, false);
  604.         }
  605.        
  606.         public static Attribute GetCustomAttribute(Module element, Type attributeType)
  607.         {
  608.             return GetCustomAttribute(element, attributeType, true);
  609.         }
  610.        
  611.         public static Attribute GetCustomAttribute(Module element, Type attributeType, bool inherit)
  612.         {
  613.             // Returns an Attribute of base class/inteface attributeType on the Module or null if none exists.
  614.             // throws an AmbiguousMatchException if there are more than one defined.
  615.             Attribute[] attrib = GetCustomAttributes(element, attributeType, inherit);
  616.            
  617.             if (attrib == null || attrib.Length == 0)
  618.                 return null;
  619.            
  620.             if (attrib.Length == 1)
  621.                 return attrib[0];
  622.            
  623.             throw new AmbiguousMatchException(Environment.GetResourceString("RFLCT.AmbigCust"));
  624.         }
  625.        
  626.         #endregion
  627.        
  628.         #region Assembly
  629.         public static Attribute[] GetCustomAttributes(Assembly element, Type attributeType)
  630.         {
  631.             return GetCustomAttributes(element, attributeType, true);
  632.         }
  633.        
  634.         public static Attribute[] GetCustomAttributes(Assembly element, Type attributeType, bool inherit)
  635.         {
  636.             if (element == null)
  637.                 throw new ArgumentNullException("element");
  638.            
  639.             if (attributeType == null)
  640.                 throw new ArgumentNullException("attributeType");
  641.            
  642.             if (!attributeType.IsSubclassOf(typeof(Attribute)) && attributeType != typeof(Attribute))
  643.                 throw new ArgumentException(Environment.GetResourceString("Argument_MustHaveAttributeBaseClass"));
  644.            
  645.             return (Attribute[])element.GetCustomAttributes(attributeType, inherit);
  646.         }
  647.        
  648.         public static Attribute[] GetCustomAttributes(Assembly element)
  649.         {
  650.             return GetCustomAttributes(element, true);
  651.         }
  652.        
  653.         public static Attribute[] GetCustomAttributes(Assembly element, bool inherit)
  654.         {
  655.             if (element == null)
  656.                 throw new ArgumentNullException("element");
  657.            
  658.             return (Attribute[])element.GetCustomAttributes(typeof(Attribute), inherit);
  659.         }
  660.        
  661.         public static bool IsDefined(Assembly element, Type attributeType)
  662.         {
  663.             return IsDefined(element, attributeType, true);
  664.         }
  665.        
  666.         public static bool IsDefined(Assembly element, Type attributeType, bool inherit)
  667.         {
  668.             // Returns true is a custom attribute subclass of attributeType class/interface with no inheritance walk
  669.             if (element == null)
  670.                 throw new ArgumentNullException("element");
  671.            
  672.             if (attributeType == null)
  673.                 throw new ArgumentNullException("attributeType");
  674.            
  675.             if (!attributeType.IsSubclassOf(typeof(Attribute)) && attributeType != typeof(Attribute))
  676.                 throw new ArgumentException(Environment.GetResourceString("Argument_MustHaveAttributeBaseClass"));
  677.            
  678.             return element.IsDefined(attributeType, false);
  679.         }
  680.        
  681.         public static Attribute GetCustomAttribute(Assembly element, Type attributeType)
  682.         {
  683.             return GetCustomAttribute(element, attributeType, true);
  684.         }
  685.        
  686.         public static Attribute GetCustomAttribute(Assembly element, Type attributeType, bool inherit)
  687.         {
  688.             // Returns an Attribute of base class/inteface attributeType on the Assembly or null if none exists.
  689.             // throws an AmbiguousMatchException if there are more than one defined.
  690.             Attribute[] attrib = GetCustomAttributes(element, attributeType, inherit);
  691.            
  692.             if (attrib == null || attrib.Length == 0)
  693.                 return null;
  694.            
  695.             if (attrib.Length == 1)
  696.                 return attrib[0];
  697.            
  698.             throw new AmbiguousMatchException(Environment.GetResourceString("RFLCT.AmbigCust"));
  699.         }
  700.        
  701.         #endregion
  702.        
  703.         #endregion
  704.        
  705.         #region Constructor
  706.         protected Attribute()
  707.         {
  708.         }
  709.         #endregion
  710.        
  711.         #region Object Overrides
  712.         public override bool Equals(object obj)
  713.         {
  714.             if (obj == null)
  715.                 return false;
  716.            
  717.             RuntimeType thisType = (RuntimeType)this.GetType();
  718.             RuntimeType thatType = (RuntimeType)obj.GetType();
  719.            
  720.             if (thatType != thisType)
  721.                 return false;
  722.            
  723.             object thisObj = this;
  724.             object thisResult;
  725.             object thatResult;
  726.            
  727.             FieldInfo[] thisFields = thisType.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
  728.            
  729.             for (int i = 0; i < thisFields.Length; i++) {
  730.                 thisResult = ((RuntimeFieldInfo)thisFields[i]).GetValue(thisObj);
  731.                 thatResult = ((RuntimeFieldInfo)thisFields[i]).GetValue(obj);
  732.                
  733.                 if (thisResult == null) {
  734.                     if (thatResult != null)
  735.                         return false;
  736.                 }
  737.                 else if (!thisResult.Equals(thatResult)) {
  738.                     return false;
  739.                 }
  740.             }
  741.            
  742.             return true;
  743.         }
  744.        
  745.         public override int GetHashCode()
  746.         {
  747.             Type type = GetType();
  748.            
  749.             FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
  750.             object vThis = null;
  751.            
  752.             for (int i = 0; i < fields.Length; i++) {
  753.                 FieldInfo field = fields[i];
  754.                
  755.                 vThis = field.GetValue(this);
  756.                
  757.                 if (vThis != null)
  758.                     break;
  759.             }
  760.            
  761.             if (vThis != null)
  762.                 return vThis.GetHashCode();
  763.            
  764.             return type.GetHashCode();
  765.         }
  766.         #endregion
  767.        
  768.         #region Public Virtual Members
  769.         public virtual object TypeId {
  770.             get { return GetType(); }
  771.         }
  772.        
  773.         public virtual bool Match(object obj)
  774.         {
  775.             return Equals(obj);
  776.         }
  777.         #endregion
  778.        
  779.         #region Public Members
  780.         public virtual bool IsDefaultAttribute()
  781.         {
  782.             return false;
  783.         }
  784.         #endregion
  785.        
  786.         void _Attribute.GetTypeInfoCount(out uint pcTInfo)
  787.         {
  788.             throw new NotImplementedException();
  789.         }
  790.        
  791.         void _Attribute.GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo)
  792.         {
  793.             throw new NotImplementedException();
  794.         }
  795.        
  796.         void _Attribute.GetIDsOfNames(        [In()]
  797. ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)
  798.         {
  799.             throw new NotImplementedException();
  800.         }
  801.        
  802.         void _Attribute.Invoke(uint dispIdMember,         [In()]
  803. ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr)
  804.         {
  805.             throw new NotImplementedException();
  806.         }
  807.     }
  808. }

Developer Fusion