Giter Club home page Giter Club logo

Comments (3)

stakx avatar stakx commented on July 18, 2024

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.

from core.

stakx avatar stakx commented on July 18, 2024

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:

private bool EqualSignatureTypes(Type x, Type y)
{
if (x.IsGenericParameter != y.IsGenericParameter)
{
return false;
}
else if (x.IsGenericType != y.IsGenericType)
{
return false;
}
if (x.IsGenericParameter)
{
if (x.GenericParameterPosition != y.GenericParameterPosition)
{
return false;
}
}
else if (x.IsGenericType)
{
var xGenericTypeDef = x.GetGenericTypeDefinition();
var yGenericTypeDef = y.GetGenericTypeDefinition();
if (xGenericTypeDef != yGenericTypeDef)
{
return false;
}
var xArgs = x.GetGenericArguments();
var yArgs = y.GetGenericArguments();
if (xArgs.Length != yArgs.Length)
{
return false;
}
for (var i = 0; i < xArgs.Length; ++i)
{
if(!EqualSignatureTypes(xArgs[i], yArgs[i])) return false;
}
}
else
{
if (!x.Equals(y))
{
return false;
}
}
return true;
}

When given two matching generic types (or type parameters) by-ref (in our repro code: the out T result parameters' types), this method claims that they do not match. This could possibly be fixed by introducing some new logic that erases by-ref-ness for further comparisons:

 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)
     ...

But I haven't checked yet whether this code breaks any existing test cases.

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).

from core.

stakx avatar stakx commented on July 18, 2024

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)
     ...

from core.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.