Skip to content

Commit 2537a23

Browse files
authored
Merge pull request castleproject#657 from stakx/bug/method-invocation-target
Fix `ArgumentException`: "Could not find method overriding method" with overridden class method having generic by-ref parameter
2 parents dca4ed0 + d7d8f6d commit 2537a23

File tree

3 files changed

+34
-1
lines changed

3 files changed

+34
-1
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ Enhancements:
66
- Two new generic method overloads `proxyGenerator.CreateClassProxy<TClass>([options], constructorArguments, interceptors)` (@backstromjoel, #636)
77
- 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)
88

9+
Bugfixes:
10+
- `ArgumentException`: "Could not find method overriding method" with overridden class method having generic by-ref parameter (@stakx, #657)
11+
912
## 5.1.1 (2022-12-30)
1013

1114
Bugfixes:

src/Castle.Core.Tests/DynamicProxy.Tests/OutRefParamsTestCase.cs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,17 @@ public virtual void MyMethodWithStruct(ref MyStruct s)
9292
}
9393
}
9494

95+
public class Factory
96+
{
97+
public virtual void Create<T>(out T result) => result = default(T);
98+
}
99+
100+
public class DerivedFactory : Factory
101+
{
102+
public override void Create<T>(out T result) => result = default(T);
103+
104+
}
105+
95106
[Test]
96107
public void CanAffectValueOfOutParameter()
97108
{
@@ -353,5 +364,13 @@ public void Exception_during_method_out_ref_arguments_set_interface_proxy_with_t
353364
Assert.AreEqual(23, param1);
354365
Assert.AreEqual("23", param2);
355366
}
367+
368+
[Test]
369+
public void Can_query_MethodInvocationTarget_for_overridden_class_method_having_a_generic_by_ref_parameter()
370+
{
371+
var interceptor = new WithCallbackInterceptor(invocation => _ = invocation.MethodInvocationTarget);
372+
var proxy = generator.CreateClassProxy<DerivedFactory>(interceptor);
373+
proxy.Create<object>(out _);
374+
}
356375
}
357-
}
376+
}

src/Castle.Core/DynamicProxy/Generators/MethodSignatureComparer.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,17 @@ public bool EqualReturnTypes(MethodInfo x, MethodInfo y)
103103

104104
private bool EqualSignatureTypes(Type x, Type y)
105105
{
106+
if (x.IsByRef != y.IsByRef)
107+
{
108+
return false;
109+
}
110+
else if (x.IsByRef)
111+
{
112+
// If `x` or `y` are by-ref generic types or type parameters (think `ref T` or `out T`),
113+
// the tests below would report false, so we need to erase by-ref-ness first:
114+
return EqualSignatureTypes(x.GetElementType(), y.GetElementType());
115+
}
116+
106117
if (x.IsGenericParameter != y.IsGenericParameter)
107118
{
108119
return false;

0 commit comments

Comments
 (0)