File: System\Reflection\TypeLoading\Parameters\RoFatMethodParameter.cs
Web Access
Project: src\src\libraries\System.Reflection.MetadataLoadContext\src\System.Reflection.MetadataLoadContext.csproj (System.Reflection.MetadataLoadContext)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
 
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.InteropServices;
 
namespace System.Reflection.TypeLoading
{
    /// <summary>
    /// Base class for all RoParameter's returned by MethodBase.GetParameters() that have an entry in the Param table.
    /// </summary>
    internal abstract class RoFatMethodParameter : RoMethodParameter
    {
        protected RoFatMethodParameter(IRoMethodBase roMethodBase, int position, Type parameterType)
            : base(roMethodBase, position, parameterType)
        {
            Debug.Assert(roMethodBase != null);
            Debug.Assert(parameterType != null);
        }
 
        public sealed override string? Name => _lazyName ??= ComputeName();
        protected abstract string? ComputeName();
        private volatile string? _lazyName;
 
        public sealed override ParameterAttributes Attributes => (_lazyParameterAttributes == ParameterAttributesSentinel) ? (_lazyParameterAttributes = ComputeAttributes()) : _lazyParameterAttributes;
        protected abstract ParameterAttributes ComputeAttributes();
        private const ParameterAttributes ParameterAttributesSentinel = (ParameterAttributes)(-1);
        private volatile ParameterAttributes _lazyParameterAttributes = ParameterAttributesSentinel;
 
        public sealed override IEnumerable<CustomAttributeData> CustomAttributes
        {
            get
            {
                foreach (CustomAttributeData cad in GetTrueCustomAttributes())
                    yield return cad;
 
                ParameterAttributes attributes = Attributes;
                if (0 != (attributes & ParameterAttributes.In))
                {
                    ConstructorInfo? ci = Loader.TryGetInCtor();
                    if (ci != null)
                        yield return new RoPseudoCustomAttributeData(ci);
                }
 
                if (0 != (attributes & ParameterAttributes.Out))
                {
                    ConstructorInfo? ci = Loader.TryGetOutCtor();
                    if (ci != null)
                        yield return new RoPseudoCustomAttributeData(ci);
                }
 
                if (0 != (attributes & ParameterAttributes.Optional))
                {
                    ConstructorInfo? ci = Loader.TryGetOptionalCtor();
                    if (ci != null)
                        yield return new RoPseudoCustomAttributeData(ci);
                }
 
                if (0 != (attributes & ParameterAttributes.HasFieldMarshal))
                {
                    CustomAttributeData? cad = CustomAttributeHelpers.TryComputeMarshalAsCustomAttributeData(ComputeMarshalAsAttribute, Loader);
                    if (cad != null)
                        yield return cad;
                }
            }
        }
 
        protected abstract MarshalAsAttribute ComputeMarshalAsAttribute();
 
        public abstract override bool HasDefaultValue { get; }
        public abstract override object? RawDefaultValue { get; }
 
        protected abstract IEnumerable<CustomAttributeData> GetTrueCustomAttributes();
 
        private MetadataLoadContext Loader => GetRoMethodBase().Loader;
    }
}