Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add doc for the new invoker classes #90536

Merged
merged 4 commits into from
Aug 15, 2023
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,17 @@

namespace System.Reflection
{
/// <summary>
/// Invokes the method reflected by the provided <see cref="ConstructorInfo"/>.
buyaa-n marked this conversation as resolved.
Show resolved Hide resolved
/// </summary>
/// <remarks>
/// Used for better performance than <seealso cref="ConstructorInfo.Invoke"/> when compatibility with that method
/// is not necessary and when the caller can cache the ConstructorInvoker instance for additional invoke calls.<br/>
/// Unlike <see cref="ConstructorInfo.Invoke"/>, the invoke methods do not look up default values for arguments when
/// <see cref="Type.Missing"/> is specified. In addition, the target constructor may be inlined for performance and not
/// appear in stack traces.
/// </remarks>
/// <seealso cref="MethodInvoker"/>
public sealed partial class ConstructorInvoker
{
private InvokeFunc_ObjSpanArgs? _invokeFunc_ObjSpanArgs;
Expand All @@ -24,6 +35,17 @@ public sealed partial class ConstructorInvoker
private readonly RuntimeConstructorInfo _method;
private readonly bool _needsByRefStrategy;

/// <summary>
/// Creates a new instance of ConstructorInvoker.
/// </summary>
/// <remarks>
/// For performance, the resulting instance should be cached for additional calls.
/// </remarks>
/// <param name="constructor">The constructor that will be invoked.</param>
/// <returns>An instance of a ConstructorInvoker.</returns>
/// <exception cref="ArgumentException">
/// The <paramref name="constructor"/> is not a runtime-based method.
/// </exception>
public static ConstructorInvoker Create(ConstructorInfo constructor)
{
ArgumentNullException.ThrowIfNull(constructor, nameof(constructor));
Expand All @@ -46,6 +68,21 @@ private ConstructorInvoker(RuntimeConstructorInfo constructor, RuntimeType[] arg
Initialize(argumentTypes, out _strategy, out _invokerArgFlags, out _needsByRefStrategy);
}

/// <summary>
/// Invokes the constructor using the specified parameters.
steveharter marked this conversation as resolved.
Show resolved Hide resolved
/// </summary>
/// <returns>
/// An instance of the class associated with the constructor.
/// </returns>
/// <exception cref="InvalidOperationException">
/// The type that declares the method is an open generic type.
/// </exception>
/// <exception cref="TargetParameterCountException">
/// The correct number of arguments were not provided.
/// </exception>
/// <exception cref="NotSupportedException">
/// The calling convention or signature is not supported.
/// </exception>
public object Invoke()
{
if (_argCount != 0)
Expand All @@ -56,6 +93,11 @@ public object Invoke()
return InvokeImpl(null, null, null, null);
}

/// <inheritdoc cref="Invoke()"/>
/// <param name="arg1">The first argument for the invoked method.</param>
/// <exception cref="ArgumentException">
/// The arguments do not match the signature of the invoked constructor.
/// </exception>
public object Invoke(object? arg1)
{
if (_argCount != 1)
Expand All @@ -66,6 +108,9 @@ public object Invoke(object? arg1)
return InvokeImpl(arg1, null, null, null);
}

/// <inheritdoc cref="Invoke(object?)"/>
/// <param name="arg1">The first argument for the invoked method.</param>
/// <param name="arg2">The second argument for the invoked method.</param>
public object Invoke(object? arg1, object? arg2)
{
if (_argCount != 2)
Expand All @@ -76,6 +121,10 @@ public object Invoke(object? arg1, object? arg2)
return InvokeImpl(arg1, arg2, null, null);
}

/// <inheritdoc cref="Invoke(object?)"/>
/// <param name="arg1">The first argument for the invoked method.</param>
/// <param name="arg2">The second argument for the invoked method.</param>
/// <param name="arg3">The third argument for the invoked method.</param>
public object Invoke(object? arg1, object? arg2, object? arg3)
{
if (_argCount !=3)
Expand All @@ -86,6 +135,11 @@ public object Invoke(object? arg1, object? arg2, object? arg3)
return InvokeImpl(arg1, arg2, arg3, null);
}

/// <inheritdoc cref="Invoke(object?)"/>
/// <param name="arg1">The first argument for the invoked method.</param>
/// <param name="arg2">The second argument for the invoked method.</param>
/// <param name="arg3">The third argument for the invoked method.</param>
/// <param name="arg4">The fourth argument for the invoked method.</param>
public object Invoke(object? arg1, object? arg2, object? arg3, object? arg4)
{
if (_argCount != 4)
Expand Down Expand Up @@ -137,6 +191,11 @@ private object InvokeImpl(object? arg1, object? arg2, object? arg3, object? arg4
return InvokeDirectByRef(arg1, arg2, arg3, arg4);
}

/// <inheritdoc cref="Invoke(object?)"/>
/// <param name="arguments">The arguments for the invoked constructor.</param>
/// <exception cref="ArgumentException">
/// The arguments do not match the signature of the invoked constructor.
/// </exception>
public object Invoke(Span<object?> arguments)
{
int argLen = arguments.Length;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,17 @@

namespace System.Reflection
{
/// <summary>
/// Invokes the method reflected by the provided <see cref="MethodBase"/>.
/// </summary>
/// <remarks>
/// Used for better performance than <seealso cref="MethodBase.Invoke"/> when compatibility with that method
/// is not necessary and when the caller can cache the MethodInvoker instance for additional invoke calls.<br/>
/// Unlike <see cref="MethodBase.Invoke"/>, the invoke methods do not look up default values for arguments when
/// <see cref="Type.Missing"/> is specified. In addition, the target method may be inlined for performance and not
/// appear in stack traces.
/// </remarks>
/// <seealso cref="ConstructorInvoker"/>
public sealed partial class MethodInvoker
{
private InvokeFunc_ObjSpanArgs? _invokeFunc_ObjSpanArgs;
Expand All @@ -26,6 +37,17 @@ public sealed partial class MethodInvoker
private readonly bool _needsByRefStrategy;
private readonly bool _isStatic;

/// <summary>
/// Creates a new instance of MethodInvoker.
/// </summary>
/// <remarks>
/// For performance, the resulting instance should be cached for additional calls.
/// </remarks>
/// <param name="method">The method that will be invoked.</param>
/// <returns>An instance of a MethodInvoker.</returns>
/// <exception cref="ArgumentException">
/// The <paramref name="method"/> is not a runtime-based method.
/// </exception>
public static MethodInvoker Create(MethodBase method)
{
ArgumentNullException.ThrowIfNull(method, nameof(method));
Expand Down Expand Up @@ -60,6 +82,32 @@ private MethodInvoker(MethodBase method, RuntimeType[] argumentTypes)
Initialize(argumentTypes, out _strategy, out _invokerArgFlags, out _needsByRefStrategy);
}

/// <summary>
/// Invokes the method using the specified parameters.
/// </summary>
/// <param name="obj">
/// The object on which to invoke the method. If the method is static, this argument is ignored.
/// </param>
/// <returns>
/// An object containing the return value of the invoked method,
/// or <c>null</c> if the invoked method does not have a return value.
/// </returns>
/// <exception cref="TargetException">
/// The <para>obj</para> parameter is <c>null</c> and the method is not static.
///
/// -or-
///
/// The method is not declared or inherited by the class of <para>obj</para>.
/// </exception>
/// <exception cref="InvalidOperationException">
/// The type that declares the method is an open generic type.
/// </exception>
/// <exception cref="TargetParameterCountException">
/// The correct number of arguments were not provided.
/// </exception>
/// <exception cref="NotSupportedException">
/// The calling convention or signature is not supported.
/// </exception>
public object? Invoke(object? obj)
{
if (_argCount != 0)
Expand All @@ -70,6 +118,12 @@ private MethodInvoker(MethodBase method, RuntimeType[] argumentTypes)
return InvokeImpl(obj, null, null, null, null);
}

/// <inheritdoc cref="Invoke(object?)"/>
/// <param name="obj"> The object on which to invoke the method. If the method is static, this argument is ignored. </param>
/// <param name="arg1">The first argument for the invoked method.</param>
/// <exception cref="ArgumentException">
/// The arguments do not match the signature of the invoked method.
/// </exception>
public object? Invoke(object? obj, object? arg1)
{
if (_argCount != 1)
Expand All @@ -80,6 +134,10 @@ private MethodInvoker(MethodBase method, RuntimeType[] argumentTypes)
return InvokeImpl(obj, arg1, null, null, null);
}

/// <inheritdoc cref="Invoke(object?)"/>
/// <param name="obj"> The object on which to invoke the method. If the method is static, this argument is ignored. </param>
/// <param name="arg1">The first argument for the invoked method.</param>
/// <param name="arg2">The second argument for the invoked method.</param>
public object? Invoke(object? obj, object? arg1, object? arg2)
{
if (_argCount != 2)
Expand All @@ -90,6 +148,11 @@ private MethodInvoker(MethodBase method, RuntimeType[] argumentTypes)
return InvokeImpl(obj, arg1, arg2, null, null);
}

/// <inheritdoc cref="Invoke(object?)"/>
/// <param name="obj"> The object on which to invoke the method. If the method is static, this argument is ignored. </param>
/// <param name="arg1">The first argument for the invoked method.</param>
/// <param name="arg2">The second argument for the invoked method.</param>
/// <param name="arg3">The third argument for the invoked method.</param>
public object? Invoke(object? obj, object? arg1, object? arg2, object? arg3)
{
if (_argCount != 3)
Expand All @@ -100,6 +163,12 @@ private MethodInvoker(MethodBase method, RuntimeType[] argumentTypes)
return InvokeImpl(obj, arg1, arg2, arg3, null);
}

/// <inheritdoc cref="Invoke(object?)"/>
/// <param name="obj"> The object on which to invoke the method. If the method is static, this argument is ignored. </param>
/// <param name="arg1">The first argument for the invoked method.</param>
/// <param name="arg2">The second argument for the invoked method.</param>
/// <param name="arg3">The third argument for the invoked method.</param>
/// <param name="arg4">The fourth argument for the invoked method.</param>
public object? Invoke(object? obj, object? arg1, object? arg2, object? arg3, object? arg4)
{
if (_argCount != 4)
Expand Down Expand Up @@ -156,6 +225,12 @@ private MethodInvoker(MethodBase method, RuntimeType[] argumentTypes)
return InvokeDirectByRef(obj, arg1, arg2, arg3, arg4);
}

/// <inheritdoc cref="Invoke(object?)"/>
/// <param name="obj"> The object on which to invoke the method. If the method is static, this argument is ignored. </param>
/// <param name="arguments">The arguments for the invoked method.</param>
/// <exception cref="ArgumentException">
/// The arguments do not match the signature of the invoked method.
/// </exception>
public object? Invoke(object? obj, Span<object?> arguments)
{
int argLen = arguments.Length;
Expand Down