// ==++== // // // Copyright (c) 2002 Microsoft Corporation. All rights reserved. // // The use and distribution terms for this software are contained in the file // named license.txt, which can be found in the root of this distribution. // By using this software in any fashion, you are agreeing to be bound by the // terms of this license. // // You must not remove this notice, or any other, from this software. // // // ==--== /**//*============================================================ ** ** Class: Attribute ** ** ** ** Purpose: The class used as an attribute to denote that ** another class can be used as an attribute. ** ** Date: December 7, 1999 ** ===========================================================*/ namespace System { using System; using System.Reflection; using System.Collections; /**////<include file='doc\Attribute.uex' path='docs/doc[@for="Attribute"]/*' /> [Serializable, AttributeUsageAttribute(AttributeTargets.All, Inherited =true, AllowMultiple=false)] // Base class for all attributes publicabstractclass Attribute { /**////<include file='doc\Attribute.uex' path='docs/doc[@for="Attribute.Attribute"]/*' /> protected Attribute(){} // This is a private enum used solely for the purpose of avoiding code repeat for these types /**////<include file='doc\Attribute.uex' path='docs/doc[@for="Attribute.GetCustomAttributes8"]/*' /> publicstatic Attribute[] GetCustomAttributes(MemberInfo element, Type type) { return GetCustomAttributes(element, type, true); } /**////<include file='doc\Attribute.uex' path='docs/doc[@for="Attribute.GetCustomAttributes"]/*' /> publicstatic Attribute[] GetCustomAttributes(MemberInfo element, Type type, bool inherit) { if (element ==null) thrownew ArgumentNullException("element"); if (type ==null) thrownew ArgumentNullException("type"); if (!type.IsSubclassOf(typeof(Attribute)) && type !=typeof(Attribute)) thrownew ArgumentException(Environment.GetResourceString("Argument_MustHaveAttributeBaseClass")); Object[] attributes =null; switch(element.MemberType) { case MemberTypes.Method: attributes = ((MethodInfo)element).GetCustomAttributes(type, inherit); break; case MemberTypes.TypeInfo: case MemberTypes.NestedType: attributes = ((Type)element).GetCustomAttributes(type, inherit); break; case MemberTypes.Constructor: attributes = ((ConstructorInfo)element).GetCustomAttributes(type, inherit); break; case MemberTypes.Field: attributes = ((FieldInfo)element).GetCustomAttributes(type, inherit); break; case MemberTypes.Property: return InternalGetCustomAttributes((PropertyInfo)element, type, inherit); case MemberTypes.Event: return InternalGetCustomAttributes((EventInfo)element, type, inherit); default: thrownew NotSupportedException(Environment.GetResourceString("NotSupported_UnsupportedMemberInfoTypes")); } return (Attribute[])attributes; } /**////<include file='doc\Attribute.uex' path='docs/doc[@for="Attribute.GetCustomAttributes9"]/*' /> publicstatic Attribute[] GetCustomAttributes(MemberInfo element) { return GetCustomAttributes(element, true); } /**////<include file='doc\Attribute.uex' path='docs/doc[@for="Attribute.GetCustomAttributes1"]/*' /> publicstatic Attribute[] GetCustomAttributes(MemberInfo element, bool inherit) { if (element ==null) thrownew ArgumentNullException("element"); Object[] attributes =null; switch(element.MemberType) { case MemberTypes.Method: attributes = ((MethodInfo)element).GetCustomAttributes(s_AttributeType, inherit); break; case MemberTypes.TypeInfo: case MemberTypes.NestedType: attributes = ((Type)element).GetCustomAttributes(s_AttributeType, inherit); break; case MemberTypes.Constructor: attributes = ((ConstructorInfo)element).GetCustomAttributes(s_AttributeType, inherit); break; case MemberTypes.Field: attributes = ((FieldInfo)element).GetCustomAttributes(s_AttributeType, inherit); break; case MemberTypes.Property: return InternalGetCustomAttributes((PropertyInfo)element, s_AttributeType, inherit); case MemberTypes.Event: return InternalGetCustomAttributes((EventInfo)element, s_AttributeType, inherit); default: thrownew NotSupportedException(Environment.GetResourceString("NotSupported_UnsupportedMemberInfoTypes")); } return (Attribute[])attributes; } privatestatic Attribute[] InternalGetCustomAttributes(PropertyInfo element, Type type, bool inherit) { // walk up the hierarchy chain Attribute[] attributes = (Attribute[])element.GetCustomAttributes(type, inherit); if (inherit) { // create the hashtable that keeps track of inherited types Hashtable types =new Hashtable(11); // create an array list to collect all the requested attibutes ArrayList attributeList =new ArrayList(); CopyToArrayList(attributeList, attributes, types); PropertyInfo baseProp = GetParentDefinition(element); while (baseProp !=null) { attributes = GetCustomAttributes(baseProp, type, false); AddAttributesToList(attributeList, attributes, types); baseProp = GetParentDefinition(baseProp); } return (Attribute[])attributeList.ToArray(type); } else return attributes; } privatestatic Attribute[] InternalGetCustomAttributes(EventInfo element, Type type, bool inherit) { // walk up the hierarchy chain Attribute[] attributes = (Attribute[])element.GetCustomAttributes(type, inherit); if (inherit) { // create the hashtable that keeps track of inherited types Hashtable types =new Hashtable(11); // create an array list to collect all the requested attibutes ArrayList attributeList =new ArrayList(); CopyToArrayList(attributeList, attributes, types); EventInfo baseEvent = GetParentDefinition(element); while (baseEvent !=null) { attributes = GetCustomAttributes(baseEvent, type, false); AddAttributesToList(attributeList, attributes, types); baseEvent = GetParentDefinition(baseEvent); } return (Attribute[])attributeList.ToArray(type); } else return attributes; } // // utility functions // staticprivatevoid CopyToArrayList(ArrayList attributeList, Attribute[] attributes, Hashtable types) { for (int i =0; i < attributes.Length; i++) { attributeList.Add(attributes[i]); Type attrType = attributes[i].GetType(); if (!types.Contains(attrType)) types[attrType] = InternalGetAttributeUsage(attrType); } } staticprivatevoid AddAttributesToList(ArrayList attributeList, Attribute[] attributes, Hashtable types) { for (int i =0; i < attributes.Length; i++) { Type attrType = attributes[i].GetType(); AttributeUsageAttribute usage = (AttributeUsageAttribute)types[attrType]; if (usage ==null) { // the type has never been seen before if it's inheritable add it to the list usage = InternalGetAttributeUsage(attrType); types[attrType] = usage; if (usage.Inherited) attributeList.Add(attributes[i]); } elseif (usage.Inherited && usage.AllowMultiple) // we saw this type already add it only if it is inheritable and it does allow multiple attributeList.Add(attributes[i]); } } /**////<include file='doc\Attribute.uex' path='docs/doc[@for="Attribute.GetCustomAttributes10"]/*' /> publicstatic Attribute[] GetCustomAttributes (ParameterInfo element, Type attributeType) { return (Attribute[])GetCustomAttributes (element, attributeType, true); } /**////<include file='doc\Attribute.uex' path='docs/doc[@for="Attribute.GetCustomAttributes2"]/*' /> publicstatic Attribute[] GetCustomAttributes (ParameterInfo element, Type attributeType, bool inherit) { if (element ==null) thrownew ArgumentNullException("element"); if (attributeType ==null) thrownew ArgumentNullException("attributeType"); if (!attributeType.IsSubclassOf(typeof(Attribute)) && attributeType !=typeof(Attribute)) thrownew ArgumentException(Environment.GetResourceString("Argument_MustHaveAttributeBaseClass")); MemberInfo member = element.Member; if (member.MemberType == MemberTypes.Method && inherit) return InternalParamGetCustomAttributes((MethodInfo)member, element, attributeType, inherit); return (Attribute[])element.GetCustomAttributes(attributeType, inherit); } // For ParameterInfo's we need to make sure that we chain through all the MethodInfo's in the inheritance chain that // have this ParameterInfo defined. .We pick up all the CustomAttributes for the starting ParameterInfo. We need to pick up only attributes // that are marked inherited from the remainder of the MethodInfo's in the inheritance chain. // For MethodInfo's on an interface we do not do an inheritance walk so the default ParameterInfo attributes are returned. // 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 // class inherits from and return the respective ParameterInfo attributes privatestatic Attribute[] InternalParamGetCustomAttributes(MethodInfo method, ParameterInfo param, Type type, bool inherit) { ArrayList disAllowMultiple =new ArrayList(); Object [] objAttr; if (type ==null) type = s_AttributeType; objAttr = param.GetCustomAttributes(type, false); for (int i=0;i<objAttr.Length;i++) { Type objType = objAttr[i].GetType(); AttributeUsageAttribute attribUsage = InternalGetAttributeUsage(objType); if (attribUsage.AllowMultiple ==false) disAllowMultiple.Add(objType); } // Get all the attributes that have Attribute as the base class Attribute [] ret =null; if (objAttr.Length ==0) ret = (Attribute[])Array.CreateInstance(type,0); else ret = (Attribute[])objAttr; if (method.DeclaringType ==null) // This is an interface so we are done. return ret; if (!inherit) return ret; int paramPosition = param.Position; method = method.GetParentDefinition(); while (method !=null) { // Find the ParameterInfo on this method ParameterInfo [] parameters = method.GetParameters(); param = parameters[paramPosition]; // Point to the correct ParameterInfo of the method objAttr = param.GetCustomAttributes(type, false); int count =0; for (int i=0;i<objAttr.Length;i++) { Type objType = objAttr[i].GetType(); AttributeUsageAttribute attribUsage = InternalGetAttributeUsage(objType); if ((attribUsage.Inherited) && (disAllowMultiple.Contains(objType) ==false)) { if (attribUsage.AllowMultiple ==false) disAllowMultiple.Add(objType); count++; } else objAttr[i] =null; } // Get all the attributes that have Attribute as the base class Attribute [] attributes = (Attribute[])Array.CreateInstance(type,count); count=0; for (int i=0;i<objAttr.Length;i++) { if (objAttr[i] !=null) { attributes[count] = (Attribute)objAttr[i]; count++; } } Attribute [] temp = ret; ret = (Attribute[])Array.CreateInstance(type,temp.Length + count); Array.Copy(temp,ret,temp.Length); int offset = temp.Length; for (int i=0;i<attributes.Length;i++) ret[offset + i] = attributes[i]; method = method.GetParentDefinition(); } return ret; } /**////<include file='doc\Attribute.uex' path='docs/doc[@for="Attribute.GetCustomAttributes11"]/*' /> publicstatic Attribute[] GetCustomAttributes (Module element, Type attributeType) { return GetCustomAttributes (element, attributeType, true); } /**////<include file='doc\Attribute.uex' path='docs/doc[@for="Attribute.GetCustomAttributes3"]/*' /> publicstatic Attribute[] GetCustomAttributes (Module element, Type attributeType, bool inherit) { if (element ==null) thrownew ArgumentNullException("element"); if (attributeType ==null) thrownew ArgumentNullException("attributeType"); if (!attributeType.IsSubclassOf(typeof(Attribute)) && attributeType !=typeof(Attribute)) thrownew ArgumentException(Environment.GetResourceString("Argument_MustHaveAttributeBaseClass")); return (Attribute[])element.GetCustomAttributes(attributeType, inherit); } /**////<include file='doc\Attribute.uex' path='docs/doc[@for="Attribute.GetCustomAttributes12"]/*' /> publicstatic Attribute[] GetCustomAttributes (Assembly element, Type attributeType) { return GetCustomAttributes (element, attributeType, true); } /**////<include file='doc\Attribute.uex' path='docs/doc[@for="Attribute.GetCustomAttributes4"]/*' /> publicstatic Attribute[] GetCustomAttributes (Assembly element, Type attributeType, bool inherit) { if (element ==null) thrownew ArgumentNullException("element"); if (attributeType ==null) thrownew ArgumentNullException("attributeType"); if (!attributeType.IsSubclassOf(typeof(Attribute)) && attributeType !=typeof(Attribute)) thrownew ArgumentException(Environment.GetResourceString("Argument_MustHaveAttributeBaseClass")); return (Attribute[])element.GetCustomAttributes(attributeType, inherit); } /**////<include file='doc\Attribute.uex' path='docs/doc[@for="Attribute.GetCustomAttributes13"]/*' /> publicstatic Attribute[] GetCustomAttributes(ParameterInfo element) { return GetCustomAttributes(element, true); } /**////<include file='doc\Attribute.uex' path='docs/doc[@for="Attribute.GetCustomAttributes5"]/*' /> publicstatic Attribute[] GetCustomAttributes(ParameterInfo element, bool inherit) { if (element ==null) thrownew ArgumentNullException("element"); MemberInfo member = element.Member; if (member.MemberType == MemberTypes.Method && inherit) return InternalParamGetCustomAttributes((MethodInfo)member, element, null, inherit); return (Attribute[])element.GetCustomAttributes(s_AttributeType, inherit); } /**////<include file='doc\Attribute.uex' path='docs/doc[@for="Attribute.GetCustomAttributes14"]/*' /> publicstatic Attribute[] GetCustomAttributes(Module element) { return GetCustomAttributes(element, true); } /**////<include file='doc\Attribute.uex' path='docs/doc[@for="Attribute.GetCustomAttributes6"]/*' /> publicstatic Attribute[] GetCustomAttributes(Module element, bool inherit) { if (element ==null) thrownew ArgumentNullException("element"); return (Attribute[])element.GetCustomAttributes(s_AttributeType, inherit); } /**////<include file='doc\Attribute.uex' path='docs/doc[@for="Attribute.GetCustomAttributes15"]/*' /> publicstatic Attribute[] GetCustomAttributes(Assembly element) { return GetCustomAttributes(element, true); } /**////<include file='doc\Attribute.uex' path='docs/doc[@for="Attribute.GetCustomAttributes7"]/*' /> publicstatic Attribute[] GetCustomAttributes(Assembly element, bool inherit) { if (element ==null) thrownew ArgumentNullException("element"); return (Attribute[])element.GetCustomAttributes(s_AttributeType, inherit); } /**////<include file='doc\Attribute.uex' path='docs/doc[@for="Attribute.IsDefined4"]/*' /> publicstaticbool IsDefined (MemberInfo element, Type attributeType) { return IsDefined(element, attributeType, true); } // Returns true if a custom attribute subclass of attributeType class/interface with inheritance walk /**////<include file='doc\Attribute.uex' path='docs/doc[@for="Attribute.IsDefined"]/*' /> publicstaticbool IsDefined (MemberInfo element, Type attributeType, bool inherit) { if (element ==null) thrownew ArgumentNullException("element"); if (attributeType ==null) thrownew ArgumentNullException("attributeType"); if (!attributeType.IsSubclassOf(typeof(Attribute)) && attributeType !=typeof(Attribute)) thrownew ArgumentException(Environment.GetResourceString("Argument_MustHaveAttributeBaseClass")); switch(element.MemberType) { case MemberTypes.Method: return ((MethodInfo)element).IsDefined(attributeType,inherit); case MemberTypes.TypeInfo: case MemberTypes.NestedType: return ((Type)element).IsDefined(attributeType,inherit); case MemberTypes.Constructor: return ((ConstructorInfo)element).IsDefined(attributeType,false); case MemberTypes.Field: return ((FieldInfo)element).IsDefined(attributeType,false); case MemberTypes.Property: return InternalIsDefined((PropertyInfo)element,attributeType,false); case MemberTypes.Event: return InternalIsDefined((EventInfo)element,attributeType,false); default: thrownew NotSupportedException(Environment.GetResourceString("NotSupported_UnsupportedMemberInfoTypes")); } } privatestaticbool InternalIsDefined (PropertyInfo element, Type attributeType, bool inherit) { // walk up the hierarchy chain if (element.IsDefined(attributeType, inherit)) returntrue; if (inherit) { AttributeUsageAttribute usage = InternalGetAttributeUsage(attributeType); if (!usage.Inherited) returnfalse; PropertyInfo baseProp = GetParentDefinition(element); while (baseProp !=null) { if (baseProp.IsDefined(attributeType, false)) returntrue; baseProp = GetParentDefinition(baseProp); } } returnfalse; } privatestaticbool InternalIsDefined (EventInfo element, Type attributeType, bool inherit) { // walk up the hierarchy chain if (element.IsDefined(attributeType, inherit)) returntrue; if (inherit) { AttributeUsageAttribute usage = InternalGetAttributeUsage(attributeType); if (!usage.Inherited) returnfalse; EventInfo baseEvent = GetParentDefinition(element); while (baseEvent !=null) { if (baseEvent.IsDefined(attributeType, false)) returntrue; baseEvent = GetParentDefinition(baseEvent); } } returnfalse; } /**////<include file='doc\Attribute.uex' path='docs/doc[@for="Attribute.IsDefined5"]/*' /> publicstaticbool IsDefined (ParameterInfo element, Type attributeType) { return IsDefined(element, attributeType, true); } // Returns true is a custom attribute subclass of attributeType class/interface with inheritance walk /**////<include file='doc\Attribute.uex' path='docs/doc[@for="Attribute.IsDefined1"]/*' /> publicstaticbool IsDefined (ParameterInfo element, Type attributeType, bool inherit) { if (element ==null) thrownew ArgumentNullException("element"); if (attributeType ==null) thrownew ArgumentNullException("attributeType"); if (!attributeType.IsSubclassOf(typeof(Attribute)) && attributeType !=typeof(Attribute)) thrownew ArgumentException(Environment.GetResourceString("Argument_MustHaveAttributeBaseClass")); MemberInfo member = element.Member; switch(member.MemberType) { case MemberTypes.Method: // We need to climb up the member hierarchy return InternalParamIsDefined((MethodInfo)member,element,attributeType,inherit); case MemberTypes.Constructor: return element.IsDefined(attributeType,false); case MemberTypes.Property: return element.IsDefined(attributeType,false); default: BCLDebug.Assert(false,"Invalid type for ParameterInfo member in Attribute class"); thrownew ArgumentException(Environment.GetResourceString("Argument_InvalidParamInfo")); } } /**////<include file='doc\Attribute.uex' path='docs/doc[@for="Attribute.IsDefined6"]/*' /> publicstaticbool IsDefined (Module element, Type attributeType) { return IsDefined(element, attributeType, false); } // Returns true is a custom attribute subclass of attributeType class/interface with no inheritance walk /**////<include file='doc\Attribute.uex' path='docs/doc[@for="Attribute.IsDefined2"]/*' /> publicstaticbool IsDefined (Module element, Type attributeType, bool inherit) { if (element ==null) thrownew ArgumentNullException("element"); if (attributeType ==null) thrownew ArgumentNullException("attributeType"); if (!attributeType.IsSubclassOf(typeof(Attribute)) && attributeType !=typeof(Attribute)) thrownew ArgumentException(Environment.GetResourceString("Argument_MustHaveAttributeBaseClass")); return element.IsDefined(attributeType,false); } /**////<include file='doc\Attribute.uex' path='docs/doc[@for="Attribute.IsDefined7"]/*' /> publicstaticbool IsDefined (Assembly element, Type attributeType) { return IsDefined (element, attributeType, true); } // Returns true is a custom attribute subclass of attributeType class/interface with no inheritance walk /**////<include file='doc\Attribute.uex' path='docs/doc[@for="Attribute.IsDefined3"]/*' /> publicstaticbool IsDefined (Assembly element, Type attributeType, bool inherit) { if (element ==null) thrownew ArgumentNullException("element"); if (attributeType ==null) thrownew ArgumentNullException("attributeType"); if (!attributeType.IsSubclassOf(typeof(Attribute)) && attributeType !=typeof(Attribute)) thrownew ArgumentException(Environment.GetResourceString("Argument_MustHaveAttributeBaseClass")); return element.IsDefined(attributeType, false); } // For ParameterInfo's we need to make sure that we chain through all the MethodInfo's in the inheritance chain. // We pick up all the CustomAttributes for the starting ParameterInfo. We need to pick up only attributes that are marked inherited from the remainder of the ParameterInfo's in the inheritance chain. // For MethodInfo's on an interface we do not do an inheritance walk. For ParameterInfo's on a // Class we walk up the inheritance chain but do not look at the MethodInfo's on the interfaces that the // class inherits from. privatestaticbool InternalParamIsDefined(MethodInfo method,ParameterInfo param,Type type, bool inherit) { if (param.IsDefined(type, false)) returntrue; if (method.DeclaringType ==null||!inherit) // This is an interface so we are done. returnfalse; int paramPosition = param.Position; method = method.GetParentDefinition(); while (method !=null) { ParameterInfo [] parameters = method.GetParameters(); param = parameters[paramPosition]; Object [] objAttr = param.GetCustomAttributes(type, false); for (int i=0;i<objAttr.Length;i++) { Type objType = objAttr[i].GetType(); AttributeUsageAttribute attribUsage = InternalGetAttributeUsage(objType); if ((objAttr[i] is Attribute) && (attribUsage.Inherited)) returntrue; } method = method.GetParentDefinition(); } returnfalse; } // Check if the custom attributes is Inheritable privatestatic AttributeUsageAttribute InternalGetAttributeUsage(Type type) { Object [] obj = type.GetCustomAttributes(s_AttributeUsageType, false); AttributeUsageAttribute attrib; if (obj.Length ==1) attrib = (AttributeUsageAttribute)obj[0]; else if (obj.Length ==0) attrib = AttributeUsageAttribute.Default; else thrownew FormatException(Environment.GetResourceString("Format_AttributeUsage")); return attrib; } /**////<include file='doc\Attribute.uex' path='docs/doc[@for="Attribute.GetCustomAttribute4"]/*' /> publicstatic Attribute GetCustomAttribute (MemberInfo element, Type attributeType) { return GetCustomAttribute (element, attributeType, true); } // Returns an Attribute of base class/inteface attributeType on the MemberInfo or null if none exists. // throws an AmbiguousMatchException if there are more than one defined. /**////<include file='doc\Attribute.uex' path='docs/doc[@for="Attribute.GetCustomAttribute"]/*' /> publicstatic Attribute GetCustomAttribute (MemberInfo element, Type attributeType, bool inherit) { Attribute[] attrib = GetCustomAttributes(element,attributeType,inherit); if (attrib.Length ==0) returnnull; if (attrib.Length ==1) return attrib[0]; else thrownew AmbiguousMatchException(Environment.GetResourceString("RFLCT.AmbigCust")); } /**////<include file='doc\Attribute.uex' path='docs/doc[@for="Attribute.GetCustomAttribute5"]/*' /> publicstatic Attribute GetCustomAttribute (ParameterInfo element, Type attributeType) { return GetCustomAttribute (element, attributeType, true); } // Returns an Attribute of base class/inteface attributeType on the ParameterInfo or null if none exists. // throws an AmbiguousMatchException if there are more than one defined. /**////<include file='doc\Attribute.uex' path='docs/doc[@for="Attribute.GetCustomAttribute1"]/*' /> publicstatic Attribute GetCustomAttribute (ParameterInfo element, Type attributeType, bool inherit) { Attribute[] attrib = GetCustomAttributes(element,attributeType,inherit); if (attrib.Length ==0) returnnull; if (attrib.Length ==1) return attrib[0]; else thrownew AmbiguousMatchException(Environment.GetResourceString("RFLCT.AmbigCust")); } /**////<include file='doc\Attribute.uex' path='docs/doc[@for="Attribute.GetCustomAttribute6"]/*' /> publicstatic Attribute GetCustomAttribute (Module element, Type attributeType) { return GetCustomAttribute (element, attributeType, true); } // Returns an Attribute of base class/inteface attributeType on the Module or null if none exists. // throws an AmbiguousMatchException if there are more than one defined. /**////<include file='doc\Attribute.uex' path='docs/doc[@for="Attribute.GetCustomAttribute2"]/*' /> publicstatic Attribute GetCustomAttribute (Module element, Type attributeType, bool inherit) { Attribute[] attrib = GetCustomAttributes(element,attributeType,inherit); if (attrib.Length ==0) returnnull; if (attrib.Length ==1) return attrib[0]; else thrownew AmbiguousMatchException(Environment.GetResourceString("RFLCT.AmbigCust")); } /**////<include file='doc\Attribute.uex' path='docs/doc[@for="Attribute.GetCustomAttribute7"]/*' /> publicstatic Attribute GetCustomAttribute (Assembly element, Type attributeType) { return GetCustomAttribute (element, attributeType, true); } // Returns an Attribute of base class/inteface attributeType on the Assembly or null if none exists. // throws an AmbiguousMatchException if there are more than one defined. /**////<include file='doc\Attribute.uex' path='docs/doc[@for="Attribute.GetCustomAttribute3"]/*' /> publicstatic Attribute GetCustomAttribute (Assembly element, Type attributeType, bool inherit) { Attribute[] attrib = GetCustomAttributes(element,attributeType,inherit); if (attrib.Length ==0) returnnull; if (attrib.Length ==1) return attrib[0]; else thrownew AmbiguousMatchException(Environment.GetResourceString("RFLCT.AmbigCust")); } /**////<include file='doc\Attribute.uex' path='docs/doc[@for="Attribute.TypeId"]/*' /> publicvirtual Object TypeId { get{ return GetType(); } } /**////<include file='doc\Attribute.uex' path='docs/doc[@for="Attribute.Match"]/*' /> publicvirtualbool Match(Object obj) { return Equals(obj); } /**////<include file='doc\Attribute.uex' path='docs/doc[@for="Attribute.Equals"]/*' /> ///<internalonly/> publicoverridebool Equals(Object obj){ if (obj ==null) returnfalse; BCLDebug.Assert((this.GetType() as RuntimeType) !=null,"Only RuntimeType's are supported"); RuntimeType thisType = (RuntimeType)this.GetType(); BCLDebug.Assert((obj.GetType() as RuntimeType) !=null,"Only RuntimeType's are supported"); RuntimeType thatType = (RuntimeType)obj.GetType(); if (thatType!=thisType) { returnfalse; } Object thisObj = (Object)this; Object thisResult, thatResult; FieldInfo[] thisFields = thisType.InternalGetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, false); for (int i=0; i<thisFields.Length; i++) { thisResult = ((RuntimeFieldInfo)thisFields[i]).InternalGetValue(thisObj,false); thatResult = ((RuntimeFieldInfo)thisFields[i]).InternalGetValue(obj, false); if (thisResult ==null) { if (thatResult !=null) returnfalse; } else if (!thisResult.Equals(thatResult)) { returnfalse; } } returntrue; } /**////<include file='doc\Attribute.uex' path='docs/doc[@for="Attribute.GetHashCode"]/*' /> publicoverrideint GetHashCode() { BCLDebug.Assert((this.GetType() as RuntimeType) !=null,"Only RuntimeType's are supported"); RuntimeType runtimeType = (RuntimeType)this.GetType(); FieldInfo[] fields = runtimeType.InternalGetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, false); Object vThis =null; for(int i =0; i < fields.Length; i++) { RuntimeFieldInfo runtimeField = fields[i] as RuntimeFieldInfo; vThis = runtimeField.InternalGetValue(this, false); if (vThis !=null) break; } if (vThis !=null) return vThis.GetHashCode(); return runtimeType.GetHashCode(); } /**////<include file='doc\Attribute.uex' path='docs/doc[@for="Attribute.IsDefaultAttribute"]/*' /> publicvirtualbool IsDefaultAttribute() { returnfalse; } // // utility function // staticprivate PropertyInfo GetParentDefinition(PropertyInfo property) { // for the current property get the base class of the getter and the setter, they might be different MethodInfo propAccessor = property.GetGetMethod(true); if (propAccessor ==null) propAccessor = property.GetSetMethod(true); if (propAccessor !=null) { propAccessor = propAccessor.GetParentDefinition(); if (propAccessor !=null) return propAccessor.DeclaringType.GetProperty(property.Name, property.PropertyType); } returnnull; } staticprivate EventInfo GetParentDefinition(EventInfo ev) { MethodInfo add = ev.GetAddMethod(true); if (add !=null) { add = add.GetParentDefinition(); if (add !=null) return add.DeclaringType.GetEvent(ev.Name); } returnnull; } privatestaticreadonly Type s_AttributeType =typeof(Attribute); privatestaticreadonly Type s_AttributeUsageType =typeof(AttributeUsageAttribute); } }
posted on
2005-08-04 01:42wanna
阅读(699)
评论(0)
编辑收藏举报