<PackageReference Include="Castle.Core" Version="5.2.1" />

InvocationHelper

static class InvocationHelper
using Castle.Core.Internal; using Castle.DynamicProxy.Generators; using System; using System.Reflection; using System.Runtime.CompilerServices; namespace Castle.DynamicProxy.Internal { internal static class InvocationHelper { private struct CacheKey : IEquatable<CacheKey> { public MethodInfo Method { [IsReadOnly] get; } public Type Type { [IsReadOnly] get; } public CacheKey(MethodInfo method, Type type) { Method = method; Type = type; } public bool Equals(CacheKey other) { if ((object)Method == other.Method) return (object)Type == other.Type; return false; } public override bool Equals(object obj) { if (obj == null) return false; if (obj is CacheKey) { CacheKey other = (CacheKey)obj; return Equals(other); } return false; } public override int GetHashCode() { return (((Method != (MethodInfo)null) ? Method.GetHashCode() : 0) * 397) ^ ((Type != (Type)null) ? Type.GetHashCode() : 0); } } private static readonly SynchronizedDictionary<CacheKey, MethodInfo> cache = new SynchronizedDictionary<CacheKey, MethodInfo>(); public static MethodInfo GetMethodOnObject(object target, MethodInfo proxiedMethod) { if (target == null) return null; return GetMethodOnType(target.GetType(), proxiedMethod); } public static MethodInfo GetMethodOnType(Type type, MethodInfo proxiedMethod) { if (type == (Type)null) throw new ArgumentNullException("type"); CacheKey key = new CacheKey(proxiedMethod, type); return cache.GetOrAdd(key, (CacheKey ck) => ObtainMethod(proxiedMethod, type)); } private static MethodInfo ObtainMethod(MethodInfo proxiedMethod, Type type) { Type[] array = null; if (proxiedMethod.IsGenericMethod) { array = proxiedMethod.GetGenericArguments(); proxiedMethod = proxiedMethod.GetGenericMethodDefinition(); } Type declaringType = proxiedMethod.DeclaringType; MethodInfo methodInfo = null; if (declaringType.IsInterface) { InterfaceMapping interfaceMap = type.GetInterfaceMap(declaringType); int num = Array.IndexOf(interfaceMap.InterfaceMethods, proxiedMethod); methodInfo = interfaceMap.TargetMethods[num]; } else { MethodInfo[] allInstanceMethods = type.GetAllInstanceMethods(); foreach (MethodInfo methodInfo2 in allInstanceMethods) { if (MethodSignatureComparer.Instance.Equals(methodInfo2.GetBaseDefinition(), proxiedMethod)) { methodInfo = methodInfo2; break; } } } if (methodInfo == (MethodInfo)null) throw new ArgumentException($"""{proxiedMethod}""{type}"""); if (array == null) return methodInfo; return methodInfo.MakeGenericMethod(array); } } }