-
Notifications
You must be signed in to change notification settings - Fork 466
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ArgumentException
: "Could not find method overriding method" with overridden class method having generic by-ref parameter
#655
Comments
Thanks for reporting this @rbeurskens. Don't worry about your repro code example making use of NSubstitute for now, I expect it shouldn't be too difficult figuring out the underlying calls and deriving DynamicProxy-only repro code. |
OK, it's taken me a while, but here is a corresponding DynamicProxy-only repro code example: var generator = new ProxyGenerator();
var factory = generator.CreateClassProxy<DerivedFactory>(new QueryMethodInvocationTargetInterceptor());
factory.Create<object>(out _);
class QueryMethodInvocationTargetInterceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
_ = invocation.MethodInvocationTarget;
}
}
public interface IFactory // NOTE: the issue is also reproducible without this interface
{
void Create<T>(out T result);
}
public class Factory : IFactory
{
public virtual void Create<T>(out T result) => result = default;
}
public class DerivedFactory : Factory
{
public override void Create<T>(out T result) => result = default;
} It seems that the error is caused in this method: Core/src/Castle.Core/DynamicProxy/Generators/MethodSignatureComparer.cs Lines 104 to 153 in dca4ed0
When given two matching generic types (or type parameters) by-ref (in our repro code: the private bool EqualSignatureTypes(Type x, Type y)
{
if (x.IsGenericParameter != y.IsGenericParameter)
{
return false;
}
else if (x.IsGenericType != y.IsGenericType)
{
return false;
}
+ if (x.IsByRef != y.IsByRef)
+ {
+ return false;
+ }
+
+ if (x.IsByRef)
+ {
+ x = x.GetElementType();
+ y = y.GetElementType();
+ }
+
if (x.IsGenericParameter)
...
The suggested code addition does not appear to break any existing test cases, but we should still double-check its validity, and whether it can possibly be added in a more optimal place (from a run-time performance standpoint). |
Scratch the code fix suggested above, the following would be more correct (because it doesn't skip the first two checks): private bool EqualSignatureTypes(Type x, Type y)
{
+ if (x.IsByRef != y.IsByRef)
+ {
+ return false;
+ }
+ else if (x.IsByRef)
+ {
+ return EqualSignatureTypes(x.GetElementType(), y.GetElementType());
+ }
+
if (x.IsGenericParameter != y.IsGenericParameter)
... |
ArgumentException
: "Could not find method overriding method" with overridden class method having generic by-ref parameter
Note that I encountered this using NSubstitute and I'm not using Castle.Core directly, but the stack trace comes from Castle.Core and tells me it is likely a bug and asks me to report it. (NSubstitute issue: nsubstitute/NSubstitute#716 )
Version used is 5.0.0, running on .NET Framework 4.8
This occurs when trying to configure an interception for a (generic) method (with an out argument) that is overridden but not defined on the class being proxied.
The text was updated successfully, but these errors were encountered: