MethodAccessor Class

Provides an efficient way for invoking methods via dynamically created delegates.

Definition

Namespace: KGySoft.Reflection
Assembly: KGySoft.CoreLibraries (in KGySoft.CoreLibraries.dll) Version: 8.1.0
C#
public abstract class MethodAccessor : MemberAccessor
Inheritance
Object    MemberAccessor    MethodAccessor

Remarks

You can obtain a MethodAccessor instance by the static GetAccessor method.

The Invoke(Object, Object) method can be used to invoke the method in general cases. It can be used even for methods with parameters passed by reference. To obtain the result of possible ref/ parameters, pass a preallocated array to the Invoke(Object, Object) method. The parameters passed by reference will be assigned back to the corresponding array elements.

The other non-generic Invoke overloads can be used for methods with no more than four parameters. They provide a better performance than the general Invoke(Object, Object) method but the result of parameters passed reference will not be assigned back.

If you know the parameter types at compile time (and the return type for function methods), then you can use the InvokeStaticAction/InvokeStaticFunction methods to invoke static methods. If you know also the instance type, then the InvokeInstanceAction/InvokeInstanceFunction methods can be used to invoke instance methods with better performance. These strongly typed methods can be used as long as the methods to invoke have no more than four parameters. Parameters passed by reference are also supported but only as input parameters as they are not assigned back to the caller.

The first call of these methods are slower because the delegates are generated on the first access, but further calls are much faster.

The already obtained accessors are cached so subsequent GetAccessor calls return the already created accessors unless they were dropped out from the cache, which can store about 8000 elements.

  Note

If you want to invoke a method by name rather than by a MethodInfo, then you can use the InvokeMethod methods in the Reflector class, which have some overloads with a methodName parameter.

  Caution

The invoker methods of this class in the .NET Standard 2.0 version throw a PlatformNotSupportedException on attempting to access a ref-returning method. You need to reference the .NET Standard 2.1 build or any .NET Framework or .NET Core/.NET builds to support methods with ref-returns.

Example

The following example compares the MethodAccessor class with System.Reflection alternatives on .NET 8 and .NET Framework 4.8 platforms.
C#
using System;
using System.Reflection;
using System.Runtime.Versioning;

using KGySoft.Diagnostics;
using KGySoft.Reflection;

class Example
{
    private class TestClass
    {
        public int TestMethod(int i) => i;
    }

    private static string PlatformName => ((TargetFrameworkAttribute)Attribute.GetCustomAttribute(Assembly.GetExecutingAssembly(),
        typeof(TargetFrameworkAttribute))).FrameworkDisplayName;

    static void Main()
    {
        var instance = new TestClass();
        MethodInfo method = instance.GetType().GetMethod(nameof(TestClass.TestMethod));
        MethodAccessor accessor = MethodAccessor.GetAccessor(method);
#if NET8_0_OR_GREATER
        MethodInvoker invoker = MethodInvoker.Create(method);
#endif

        new PerformanceTest { TestName = $"Method Invoke Test - {PlatformName}", Iterations = 1_000_000 }
            .AddCase(() => instance.TestMethod(1), "Direct call")
            .AddCase(() => method.Invoke(instance, new object[] { 1 }), "System.Reflection.MethodInfo.Invoke")
#if NET8_0_OR_GREATER
            .AddCase(() => invoker.Invoke(instance, 1), "System.Reflection.MethodInvoker.Invoke (.NET 8 or later)")
#endif
            .AddCase(() => accessor.Invoke(instance, 1), "MethodAccessor.Invoke")
            .AddCase(() => accessor.InvokeInstanceFunction<TestClass, int, int>(instance, 1), "MethodAccessor.InvokeInstanceFunction<,,>")
            .DoTest()
            .DumpResults(Console.Out);
    }
}

// This code example produces a similar output to these ones:

// ==[Method Invoke Test - .NET 8.0 Results]================================================
// Iterations: 1,000,000
// Warming up: Yes
// Test cases: 5
// Calling GC.Collect: Yes
// Forced CPU Affinity: No
// Cases are sorted by time (quickest first)
// --------------------------------------------------
// 1. Direct call: average time: 3.48 ms
// 2. MethodAccessor.InvokeInstanceFunction<,,>: average time: 5.78 ms (+2.30 ms / 166.09%)
// 3. MethodAccessor.Invoke: average time: 18.34 ms (+14.85 ms / 526.75%)
// 4. System.Reflection.MethodInvoker.Invoke (.NET 8 or later): average time: 28.83 ms (+25.35 ms / 828.24%)
// 5. System.Reflection.MethodInfo.Invoke: average time: 39.75 ms (+36.27 ms / 1,142.08%)

// ==[Method Invoke Test - .NET Framework 4.8 Results]================================================
// Iterations: 1,000,000
// Warming up: Yes
// Test cases: 4
// Calling GC.Collect: Yes
// Forced CPU Affinity: No
// Cases are sorted by time (quickest first)
// --------------------------------------------------
// 1. Direct call: average time: 3.41 ms
// 2. MethodAccessor.InvokeInstanceFunction<,,>: average time: 12.20 ms (+8.80 ms / 358.22%)
// 3. MethodAccessor.Invoke: average time: 29.07 ms (+25.66 ms / 853.33%)
// 4. System.Reflection.MethodInfo.Invoke: average time: 203.79 ms (+200.38 ms / 5,982.90%)

Properties

MemberInfo Gets the reflection member info of the accessed member.
(Inherited from MemberAccessor)

Methods

Equals Determines whether the specified Object is equal to the current MemberAccessor.
(Inherited from MemberAccessor)
GetAccessor Gets a MemberAccessor for the specified method.
GetHashCode Gets a hash code for the current MemberAccessor instance.
(Inherited from MemberAccessor)
Invoke(Object) Invokes the method with no parameters. The return value of void methods is always . For static methods the instance parameter is omitted (can be ).
See the Remarks section of the Invoke(Object, Object) overload for details.
Invoke(Object, Object) Invokes the method with one parameter. The return value of void methods is always . For static methods the instance parameter is omitted (can be ).
See the Remarks section of the Invoke(Object, Object) overload for details.
Invoke(Object, Object) Invokes the method. The return value of void methods is always . For static methods the instance parameter is omitted (can be ).
Invoke(Object, Object, Object) Invokes the method with two parameters. The return value of void methods is always . For static methods the instance parameter is omitted (can be ).
See the Remarks section of the Invoke(Object, Object) overload for details.
Invoke(Object, Object, Object, Object) Invokes the method with three parameters. The return value of void methods is always . For static methods the instance parameter is omitted (can be ).
See the Remarks section of the Invoke(Object, Object) overload for details.
Invoke(Object, Object, Object, Object, Object) Invokes the method with four parameters. The return value of void methods is always . For static methods the instance parameter is omitted (can be ).
See the Remarks section of the Invoke(Object, Object) overload for details.
InvokeInstanceActionTInstance(TInstance) Invokes a parameterless instance action method in a reference type. If the type of the declaring instance is not known at compile time the non-generic Invoke methods can be used.
InvokeInstanceActionTInstance(TInstance) Invokes a parameterless instance action method in a value type. If the type of the declaring instance is not known at compile time the non-generic Invoke methods can be used.
InvokeInstanceActionTInstance, T(TInstance, T) Invokes an instance action method with one parameter in a reference type. If the type of the parameter or the declaring instance are not known at compile time the non-generic Invoke methods can be used.
InvokeInstanceActionTInstance, T(TInstance, T) Invokes an instance action method with one parameter in a value type. If the type of the parameter or the declaring instance are not known at compile time the non-generic Invoke methods can be used.
InvokeInstanceActionTInstance, T1, T2(TInstance, T1, T2) Invokes an instance action method with two parameters in a reference type. If the type of the parameters or the declaring instance are not known at compile time the non-generic Invoke methods can be used.
InvokeInstanceActionTInstance, T1, T2(TInstance, T1, T2) Invokes an instance action method with two parameters in a value type. If the type of the parameters or the declaring instance are not known at compile time the non-generic Invoke methods can be used.
InvokeInstanceActionTInstance, T1, T2, T3(TInstance, T1, T2, T3) Invokes an instance action method with three parameters in a reference type. If the type of the parameters or the declaring instance are not known at compile time the non-generic Invoke methods can be used.
InvokeInstanceActionTInstance, T1, T2, T3(TInstance, T1, T2, T3) Invokes an instance action method with three parameters in a value type. If the type of the parameters or the declaring instance are not known at compile time the non-generic Invoke methods can be used.
InvokeInstanceActionTInstance, T1, T2, T3, T4(TInstance, T1, T2, T3, T4) Invokes an instance action method with four parameters in a reference type. If the type of the parameters or the declaring instance are not known at compile time the non-generic Invoke methods can be used.
InvokeInstanceActionTInstance, T1, T2, T3, T4(TInstance, T1, T2, T3, T4) Invokes an instance action method with four parameters in a value type. If the type of the parameters or the declaring instance are not known at compile time the non-generic Invoke methods can be used.
InvokeInstanceFunctionTInstance, TResult(TInstance) Invokes a parameterless instance function method in a reference type. If the type of the return value or the declaring instance are not known at compile time the non-generic Invoke methods can be used.
InvokeInstanceFunctionTInstance, TResult(TInstance) Invokes a parameterless instance function method in a value type. If the type of the return value or the declaring instance are not known at compile time the non-generic Invoke methods can be used.
InvokeInstanceFunctionTInstance, T, TResult(TInstance, T) Invokes an instance function method with one parameter in a reference type. If the type of the parameter, the return value or the declaring instance are not known at compile time the non-generic Invoke methods can be used.
InvokeInstanceFunctionTInstance, T, TResult(TInstance, T) Invokes an instance function method with one parameter in a value type. If the type of the parameter, the return value or the declaring instance are not known at compile time the non-generic Invoke methods can be used.
InvokeInstanceFunctionTInstance, T1, T2, TResult(TInstance, T1, T2) Invokes an instance function method with two parameters in a reference type. If the type of the parameters, the return value or the declaring instance are not known at compile time the non-generic Invoke methods can be used.
InvokeInstanceFunctionTInstance, T1, T2, TResult(TInstance, T1, T2) Invokes an instance function method with two parameters in a value type. If the type of the parameters, the return value or the declaring instance are not known at compile time the non-generic Invoke methods can be used.
InvokeInstanceFunctionTInstance, T1, T2, T3, TResult(TInstance, T1, T2, T3) Invokes an instance function method with three parameters in a reference type. If the type of the parameters, the return value or the declaring instance are not known at compile time the non-generic Invoke methods can be used.
InvokeInstanceFunctionTInstance, T1, T2, T3, TResult(TInstance, T1, T2, T3) Invokes an instance function method with three parameters in a value type. If the type of the parameters, the return value or the declaring instance are not known at compile time the non-generic Invoke methods can be used.
InvokeInstanceFunctionTInstance, T1, T2, T3, T4, TResult(TInstance, T1, T2, T3, T4) Invokes an instance function method with four parameters in a reference type. If the type of the parameters, the return value or the declaring instance are not known at compile time the non-generic Invoke methods can be used.
InvokeInstanceFunctionTInstance, T1, T2, T3, T4, TResult(TInstance, T1, T2, T3, T4) Invokes an instance function method with four parameters in a value type. If the type of the parameters, the return value or the declaring instance are not known at compile time the non-generic Invoke methods can be used.
InvokeStaticAction Invokes a parameterless static action method.
InvokeStaticActionT(T) Invokes a static action method with one parameter. If the type of the parameter is not known at compile time the non-generic Invoke methods can be used.
InvokeStaticActionT1, T2(T1, T2) Invokes a static action method with two parameters. If the type of the parameters are not known at compile time the non-generic Invoke methods can be used.
InvokeStaticActionT1, T2, T3(T1, T2, T3) Invokes a static action method with three parameters. If the type of the parameters are not known at compile time the non-generic Invoke methods can be used.
InvokeStaticActionT1, T2, T3, T4(T1, T2, T3, T4) Invokes a static action method with four parameters. If the type of the parameters are not known at compile time the non-generic Invoke methods can be used.
InvokeStaticFunctionTResult Invokes a parameterless static function method. If the return type is not known at compile time the non-generic Invoke methods can be used.
InvokeStaticFunctionT, TResult(T) Invokes a static function method with one parameter. If the type of the parameter or the return value are not known at compile time the non-generic Invoke methods can be used.
InvokeStaticFunctionT1, T2, TResult(T1, T2) Invokes a static function method with two parameters. If the type of the parameters or the return value are not known at compile time the non-generic Invoke methods can be used.
InvokeStaticFunctionT1, T2, T3, TResult(T1, T2, T3) Invokes a static function method with three parameters. If the type of the parameters or the return value are not known at compile time the non-generic Invoke methods can be used.
InvokeStaticFunctionT1, T2, T3, T4, TResult(T1, T2, T3, T4) Invokes a static function method with four parameters. If the type of the parameters or the return value are not known at compile time the non-generic Invoke methods can be used.
ToString Returns a String that represents the current MemberAccessor.
(Inherited from MemberAccessor)

Extension Methods

Convert Converts an Object specified in the obj parameter to the desired targetType.
See the Examples section of the generic ConvertTTarget(Object, CultureInfo) overload for an example.
(Defined by ObjectExtensions)
ConvertTTarget Converts an Object specified in the obj parameter to the desired TTarget.
(Defined by ObjectExtensions)
In Gets whether item is among the elements of set.
See the Examples section of the generic InT(T, T) overload for an example.
(Defined by ObjectExtensions)
TryConvert Tries to convert an Object specified in the obj parameter to the desired targetType.
See the Examples section of the ConvertTTarget(Object, CultureInfo) method for a related example.
(Defined by ObjectExtensions)
TryConvert Tries to convert an Object specified in the obj parameter to the desired targetType.
See the Examples section of the ConvertTTarget(Object, CultureInfo) method for a related example.
(Defined by ObjectExtensions)
TryConvertTTarget Tries to convert an Object specified in the obj parameter to the desired TTarget.
See the Examples section of the ConvertTTarget(Object, CultureInfo) method for a related example.
(Defined by ObjectExtensions)
TryConvertTTarget Tries to convert an Object specified in the obj parameter to the desired TTarget.
See the Examples section of the ConvertTTarget(Object, CultureInfo) method for a related example.
(Defined by ObjectExtensions)

See Also