示例#1
0
        /// <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)) };
        /// <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));
        }