/// <summary> /// Convert MarshalAsAttribute data into CustomAttributeData form. Returns null if the core assembly cannot be loaded or if the necessary /// types aren't in the core assembly. /// </summary> public static CustomAttributeData?TryComputeMarshalAsCustomAttributeData(Func <MarshalAsAttribute> marshalAsAttributeComputer, MetadataLoadContext loader) { // Make sure all the necessary framework types exist in this MetadataLoadContext's core assembly. If one doesn't, skip. CoreTypes ct = loader.GetAllFoundCoreTypes(); if (ct[CoreType.String] == null || ct[CoreType.Boolean] == null || ct[CoreType.UnmanagedType] == null || ct[CoreType.VarEnum] == null || ct[CoreType.Type] == null || ct[CoreType.Int16] == null || ct[CoreType.Int32] == null) { return(null); } ConstructorInfo?ci = loader.TryGetMarshalAsCtor(); if (ci == null) { return(null); } Func <CustomAttributeArguments> argumentsPromise = () => { // The expensive work goes in here. It will not execute unless someone invokes the Constructor/NamedArguments properties on // the CustomAttributeData. MarshalAsAttribute ma = marshalAsAttributeComputer(); Type attributeType = ci.DeclaringType !; CustomAttributeTypedArgument[] cats = { new CustomAttributeTypedArgument(ct[CoreType.UnmanagedType] !, (int)(ma.Value)) };
public static PrimitiveTypeCode GetEnumUnderlyingPrimitiveTypeCode(this Type enumType, MetadataLoadContext loader) { Type type = enumType.GetEnumUnderlyingType(); CoreTypes coreTypes = loader.GetAllFoundCoreTypes(); // Be careful how you compare - one or more elements of "coreTypes" can be null! if (type == coreTypes[CoreType.Boolean]) { return(PrimitiveTypeCode.Boolean); } if (type == coreTypes[CoreType.Char]) { return(PrimitiveTypeCode.Char); } if (type == coreTypes[CoreType.Byte]) { return(PrimitiveTypeCode.Byte); } if (type == coreTypes[CoreType.Int16]) { return(PrimitiveTypeCode.Int16); } if (type == coreTypes[CoreType.Int32]) { return(PrimitiveTypeCode.Int32); } if (type == coreTypes[CoreType.Int64]) { return(PrimitiveTypeCode.Int64); } if (type == coreTypes[CoreType.IntPtr]) { return(PrimitiveTypeCode.IntPtr); } if (type == coreTypes[CoreType.SByte]) { return(PrimitiveTypeCode.SByte); } if (type == coreTypes[CoreType.UInt16]) { return(PrimitiveTypeCode.UInt16); } if (type == coreTypes[CoreType.UInt32]) { return(PrimitiveTypeCode.UInt32); } if (type == coreTypes[CoreType.UInt64]) { return(PrimitiveTypeCode.UInt64); } if (type == coreTypes[CoreType.UIntPtr]) { return(PrimitiveTypeCode.UIntPtr); } throw new BadImageFormatException(SR.Format(SR.UnexpectedUnderlyingEnumType, enumType, type)); }
/// <summary> /// Convert MarshalAsAttribute data into CustomAttributeData form. Returns null if the core assembly cannot be loaded or if the necessary /// types aren't in the core assembly. /// </summary> public static CustomAttributeData TryComputeMarshalAsCustomAttributeData(Func <MarshalAsAttribute> marshalAsAttributeComputer, MetadataLoadContext loader) { // Make sure all the necessary framework types exist in this MetadataLoadContext's core assembly. If one doesn't, skip. CoreTypes ct = loader.GetAllFoundCoreTypes(); if (ct[CoreType.String] == null || ct[CoreType.Boolean] == null || ct[CoreType.UnmanagedType] == null || ct[CoreType.VarEnum] == null || ct[CoreType.Type] == null || ct[CoreType.Int16] == null || ct[CoreType.Int32] == null) { return(null); } ConstructorInfo ci = loader.TryGetMarshalAsCtor(); if (ci == null) { return(null); } Func <CustomAttributeArguments> argumentsPromise = () => { // The expensive work goes in here. It will not execute unless someone invokes the Constructor/NamedArguments properties on // the CustomAttributeData. MarshalAsAttribute ma = marshalAsAttributeComputer(); Type attributeType = ci.DeclaringType; CustomAttributeTypedArgument[] cats = { new CustomAttributeTypedArgument(ct[CoreType.UnmanagedType], (int)(ma.Value)) }; List <CustomAttributeNamedArgument> cans = new List <CustomAttributeNamedArgument>(); cans.AddRange(new CustomAttributeNamedArgument[] { attributeType.ToCustomAttributeNamedArgument(nameof(MarshalAsAttribute.ArraySubType), ct[CoreType.UnmanagedType], (int)ma.ArraySubType), attributeType.ToCustomAttributeNamedArgument(nameof(MarshalAsAttribute.IidParameterIndex), ct[CoreType.Int32], ma.IidParameterIndex), attributeType.ToCustomAttributeNamedArgument(nameof(MarshalAsAttribute.SafeArraySubType), ct[CoreType.VarEnum], (int)ma.SafeArraySubType), attributeType.ToCustomAttributeNamedArgument(nameof(MarshalAsAttribute.SizeConst), ct[CoreType.Int32], ma.SizeConst), attributeType.ToCustomAttributeNamedArgument(nameof(MarshalAsAttribute.SizeParamIndex), ct[CoreType.Int16], ma.SizeParamIndex), }); if (ma.SafeArrayUserDefinedSubType != null) { cans.Add(attributeType.ToCustomAttributeNamedArgument(nameof(MarshalAsAttribute.SafeArrayUserDefinedSubType), ct[CoreType.Type], ma.SafeArrayUserDefinedSubType)); } if (ma.MarshalType != null) { cans.Add(attributeType.ToCustomAttributeNamedArgument(nameof(MarshalAsAttribute.MarshalType), ct[CoreType.String], ma.MarshalType)); } if (ma.MarshalTypeRef != null) { cans.Add(attributeType.ToCustomAttributeNamedArgument(nameof(MarshalAsAttribute.MarshalTypeRef), ct[CoreType.Type], ma.MarshalTypeRef)); } if (ma.MarshalCookie != null) { cans.Add(attributeType.ToCustomAttributeNamedArgument(nameof(MarshalAsAttribute.MarshalCookie), ct[CoreType.String], ma.MarshalCookie)); } return(new CustomAttributeArguments(cats, cans)); }; return(new RoPseudoCustomAttributeData(ci, argumentsPromise)); }