Skip to content

Commit

Permalink
Merge pull request #657 from stakx/bug/method-invocation-target
Browse files Browse the repository at this point in the history
Fix `ArgumentException`: "Could not find method overriding method" with overridden class method having generic by-ref parameter
  • Loading branch information
stakx committed Aug 28, 2023
2 parents dca4ed0 + d7d8f6d commit 2537a23
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 1 deletion.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Expand Up @@ -6,6 +6,9 @@ Enhancements:
- Two new generic method overloads `proxyGenerator.CreateClassProxy<TClass>([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:
Expand Down
21 changes: 20 additions & 1 deletion src/Castle.Core.Tests/DynamicProxy.Tests/OutRefParamsTestCase.cs
Expand Up @@ -92,6 +92,17 @@ public virtual void MyMethodWithStruct(ref MyStruct s)
}
}

public class Factory
{
public virtual void Create<T>(out T result) => result = default(T);
}

public class DerivedFactory : Factory
{
public override void Create<T>(out T result) => result = default(T);

}

[Test]
public void CanAffectValueOfOutParameter()
{
Expand Down Expand Up @@ -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<DerivedFactory>(interceptor);
proxy.Create<object>(out _);
}
}
}
}
11 changes: 11 additions & 0 deletions src/Castle.Core/DynamicProxy/Generators/MethodSignatureComparer.cs
Expand Up @@ -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;
Expand Down

0 comments on commit 2537a23

Please sign in to comment.