diff --git a/CHANGELOG.md b/CHANGELOG.md index f55c028476..0309e13178 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,9 @@ Enhancements: - Two new generic method overloads `proxyGenerator.CreateClassProxy([options], constructorArguments, interceptors)` (@backstromjoel, #636) - Allow specifying which attributes should always be copied to proxy class by adding attribute type to `AttributesToAlwaysReplicate`. Previously only non-inherited, with `Inherited=false`, attributes were copied. (@shoaibshakeel381, #633) +Bugfixes: +- `ArgumentException`: "Could not find method overriding method" with overridden class method having generic by-ref parameter (@stakx, #657) + ## 5.1.1 (2022-12-30) Bugfixes: diff --git a/src/Castle.Core.Tests/DynamicProxy.Tests/OutRefParamsTestCase.cs b/src/Castle.Core.Tests/DynamicProxy.Tests/OutRefParamsTestCase.cs index 4f28a939f2..39b6b1be34 100644 --- a/src/Castle.Core.Tests/DynamicProxy.Tests/OutRefParamsTestCase.cs +++ b/src/Castle.Core.Tests/DynamicProxy.Tests/OutRefParamsTestCase.cs @@ -92,6 +92,17 @@ public virtual void MyMethodWithStruct(ref MyStruct s) } } + public class Factory + { + public virtual void Create(out T result) => result = default(T); + } + + public class DerivedFactory : Factory + { + public override void Create(out T result) => result = default(T); + + } + [Test] public void CanAffectValueOfOutParameter() { @@ -353,5 +364,13 @@ public void Exception_during_method_out_ref_arguments_set_interface_proxy_with_t Assert.AreEqual(23, param1); Assert.AreEqual("23", param2); } + + [Test] + public void Can_query_MethodInvocationTarget_for_overridden_class_method_having_a_generic_by_ref_parameter() + { + var interceptor = new WithCallbackInterceptor(invocation => _ = invocation.MethodInvocationTarget); + var proxy = generator.CreateClassProxy(interceptor); + proxy.Create(out _); + } } -} \ No newline at end of file +} diff --git a/src/Castle.Core/DynamicProxy/Generators/MethodSignatureComparer.cs b/src/Castle.Core/DynamicProxy/Generators/MethodSignatureComparer.cs index 82cd760020..eae924c178 100644 --- a/src/Castle.Core/DynamicProxy/Generators/MethodSignatureComparer.cs +++ b/src/Castle.Core/DynamicProxy/Generators/MethodSignatureComparer.cs @@ -103,6 +103,17 @@ public bool EqualReturnTypes(MethodInfo x, MethodInfo y) private bool EqualSignatureTypes(Type x, Type y) { + if (x.IsByRef != y.IsByRef) + { + return false; + } + else if (x.IsByRef) + { + // If `x` or `y` are by-ref generic types or type parameters (think `ref T` or `out T`), + // the tests below would report false, so we need to erase by-ref-ness first: + return EqualSignatureTypes(x.GetElementType(), y.GetElementType()); + } + if (x.IsGenericParameter != y.IsGenericParameter) { return false;