|
// 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.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Reflection.Runtime.ParameterInfos;
using Internal.Reflection.Core.Execution;
namespace System.Reflection.Runtime.MethodInfos
{
//
// The runtime's implementation of ConstructorInfo.
//
internal abstract partial class RuntimeConstructorInfo : ConstructorInfo
{
public abstract override MethodAttributes Attributes { get; }
public abstract override CallingConventions CallingConvention { get; }
public sealed override bool ContainsGenericParameters
{
get
{
return DeclaringType.ContainsGenericParameters;
}
}
public abstract override IEnumerable<CustomAttributeData> CustomAttributes { get; }
public abstract override Type DeclaringType { get; }
[RequiresUnreferencedCode("Trimming may change method bodies. For example it can change some instructions, remove branches or local variables.")]
public sealed override MethodBody GetMethodBody()
{
throw new PlatformNotSupportedException();
}
public sealed override ParameterInfo[] GetParameters()
{
RuntimeParameterInfo[] parameters = RuntimeParameters;
if (parameters.Length == 0)
return Array.Empty<ParameterInfo>();
ParameterInfo[] result = new ParameterInfo[parameters.Length];
for (int i = 0; i < result.Length; i++)
result[i] = parameters[i];
return result;
}
public sealed override ReadOnlySpan<ParameterInfo> GetParametersAsSpan()
{
return RuntimeParameters;
}
public abstract override bool HasSameMetadataDefinitionAs(MemberInfo other);
public abstract override object Invoke(BindingFlags invokeAttr, Binder? binder, object?[]? parameters, CultureInfo? culture);
[DebuggerGuidedStepThrough]
public sealed override object Invoke(object? obj, BindingFlags invokeAttr, Binder? binder, object?[]? parameters, CultureInfo? culture)
{
parameters ??= Array.Empty<object>();
MethodBaseInvoker methodInvoker;
try
{
methodInvoker = this.MethodInvoker;
}
catch (Exception)
{
//
// Project N compat note: On the desktop, ConstructorInfo.Invoke(Object[]) specifically forbids invoking static constructors (and
// for us, that check is embedded inside the MethodInvoker property call.) Howver, MethodBase.Invoke(Object, Object[]) allows it. This was
// probably an oversight on the desktop. We choose not to support this loophole on Project N for the following reasons:
//
// 1. The Project N toolchain aggressively replaces static constructors with static initialization data whenever possible.
// So the static constructor may no longer exist.
//
// 2. Invoking the static constructor through Reflection is not very useful as it invokes the static constructor whether or not
// it was already run. Since static constructors are specifically one-shot deals, this will almost certainly mess up the
// type's internal assumptions.
//
if (this.IsStatic)
throw new PlatformNotSupportedException(SR.Acc_NotClassInit);
throw;
}
object? result = methodInvoker.Invoke(obj, parameters, binder, invokeAttr, culture);
DebugAnnotations.PreviousCallContainsDebuggerStepInCode();
return result!;
}
internal abstract override MethodBase MetadataDefinitionMethod { get; }
public abstract override int MetadataToken
{
get;
}
public sealed override Module Module
{
get
{
return DeclaringType.Module;
}
}
public sealed override bool IsConstructedGenericMethod
{
get
{
return false;
}
}
public sealed override bool IsGenericMethod
{
get
{
return false;
}
}
public sealed override bool IsGenericMethodDefinition
{
get
{
return false;
}
}
public abstract override MethodImplAttributes MethodImplementationFlags { get; }
public abstract override string Name { get; }
public abstract override bool Equals(object obj);
public abstract override int GetHashCode();
public sealed override Type ReflectedType
{
get
{
// Constructors are always looked up as if BindingFlags.DeclaredOnly were specified. Thus, the ReflectedType will always be the DeclaringType.
return DeclaringType;
}
}
public abstract override string ToString();
public abstract override RuntimeMethodHandle MethodHandle { get; }
protected internal MethodBaseInvoker MethodInvoker
{
get
{
return _lazyMethodInvoker ??= UncachedMethodInvoker;
}
}
internal IntPtr LdFtnResult => MethodInvoker.LdFtnResult;
protected abstract RuntimeParameterInfo[] RuntimeParameters { get; }
protected abstract MethodBaseInvoker UncachedMethodInvoker { get; }
private volatile MethodBaseInvoker _lazyMethodInvoker;
}
}
|