// // If throwIfMissingMetadata is false, returns null rather than throwing a MissingMetadataException. // internal sealed override IList <CustomAttributeNamedArgument> GetNamedArguments(bool throwIfMissingMetadata) { LowLevelListWithIList <CustomAttributeNamedArgument> customAttributeNamedArguments = new LowLevelListWithIList <CustomAttributeNamedArgument>(); foreach (NamedArgumentHandle namedArgumentHandle in _customAttribute.NamedArguments) { NamedArgument namedArgument = namedArgumentHandle.GetNamedArgument(_reader); String memberName = namedArgument.Name.GetString(_reader); bool isField = (namedArgument.Flags == NamedArgumentMemberKind.Field); CustomAttributeTypedArgument typedValue = ParseFixedArgument( _reader, namedArgument.Value, throwIfMissingMetadata, delegate() { // We got here because the custom attribute blob did not inclue type information. For named arguments, this is considered illegal metadata // (ECMA always includes type info for named arguments.) throw new BadImageFormatException(); } ); if (typedValue.ArgumentType == null) { Debug.Assert(!throwIfMissingMetadata); return(null); } customAttributeNamedArguments.Add(ExtensibleCustomAttributeData.CreateCustomAttributeNamedArgument(this.AttributeType, memberName, isField, typedValue)); } return(customAttributeNamedArguments); }
public sealed override IEnumerable <CustomAttributeData> GetPsuedoCustomAttributes(MetadataReader reader, FieldHandle fieldHandle, TypeDefinitionHandle declaringTypeHandle) { TypeAttributes layoutKind = declaringTypeHandle.GetTypeDefinition(reader).Flags & TypeAttributes.LayoutMask; if (layoutKind == TypeAttributes.ExplicitLayout) { int offset = (int)(fieldHandle.GetField(reader).Offset); CustomAttributeTypedArgument offsetArgument = ExtensibleCustomAttributeData.CreateCustomAttributeTypedArgument(typeof(Int32), offset); yield return(ReflectionCoreExecution.ExecutionDomain.GetCustomAttributeData(typeof(FieldOffsetAttribute), new CustomAttributeTypedArgument[] { offsetArgument }, null)); } }
// // Wrap a custom attribute argument (or an element of an array-typed custom attribute argument) in a CustomAttributeTypeArgument structure // for insertion into a CustomAttributeData value. // private CustomAttributeTypedArgument WrapInCustomAttributeTypedArgument(Object value, Type argumentType) { // To support reflection domains other than the execution domain, we'll have to translate argumentType to one of the values off // _reflectionDomain.FoundationTypes rather than using the direct value of value.GetType(). It's unclear how to do this for // enum types. Cross that bridge if ever get to it. Debug.Assert(_reflectionDomain is ExecutionDomain); if (argumentType.Equals(typeof(Object))) { // If the declared attribute type is System.Object, we must report the type based on the runtime value. if (value == null) { argumentType = typeof(String); // Why is null reported as System.String? Because that's what the desktop CLR does. } else if (value is Type) { argumentType = typeof(Type); // value.GetType() will not actually be System.Type - rather it will be some internal implementation type. We only want to report it as System.Type. } else { argumentType = value.GetType(); } } Array arrayValue = value as Array; if (arrayValue != null) { if (!argumentType.IsArray) { throw new BadImageFormatException(); } Type reportedElementType = argumentType.GetElementType(); LowLevelListWithIList <CustomAttributeTypedArgument> elementTypedArguments = new LowLevelListWithIList <CustomAttributeTypedArgument>(); foreach (Object elementValue in arrayValue) { CustomAttributeTypedArgument elementTypedArgument = WrapInCustomAttributeTypedArgument(elementValue, reportedElementType); elementTypedArguments.Add(elementTypedArgument); } return(ExtensibleCustomAttributeData.CreateCustomAttributeTypedArgument(argumentType, new ReadOnlyCollection <CustomAttributeTypedArgument>(elementTypedArguments))); } else { return(ExtensibleCustomAttributeData.CreateCustomAttributeTypedArgument(argumentType, value)); } }