Skip to content

Commit

Permalink
Add missing equality checks to MethodSignatureComparer.EqualSignature…
Browse files Browse the repository at this point in the history
…Types
  • Loading branch information
stakx authored and jonorossi committed Oct 9, 2017
1 parent 6fb2df5 commit 26ad75d
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 4 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Castle Core Changelog

## Unreleased

Bugfixes:
- Add missing equality checks in `MethodSignatureComparer.EqualSignatureTypes` to fix `TypeLoadException`s ("Method does not have an implementation") (@stakx, #310)

## 4.2.0 (2017-09-28)

Enhancements:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,13 @@ public void NonVirtualExplicitInterfaceMethods_AreIgnored_OnClassProxy()

Assert.AreEqual(5, result);
}

[Test]
public void CreateClassProxy_GivenAdditionalInterfaceWithOverloadedGenericMethodsHavingGenericParameter_SuccessfullyCreatesProxyInstance()
{
var instance = generator.CreateClassProxy(typeof(object), new Type[] { typeof(InterfaceWithOverloadedGenericMethod) }, interceptor);
Assert.NotNull(instance);
}
}

public class ExplicitInterfaceWithPropertyImplementation : ISimpleInterfaceWithProperty
Expand All @@ -185,4 +192,18 @@ public int Age
get { throw new NotImplementedException(); }
}
}

public interface InterfaceWithOverloadedGenericMethod
{
void GenericMethod<T>(GenericClass1<T> arg);
void GenericMethod<T>(GenericClass2<T> arg);
}

public class GenericClass1<T>
{
}

public class GenericClass2<T>
{
}
}
23 changes: 23 additions & 0 deletions src/Castle.Core.Tests/MethodComparerTestCase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -355,5 +355,28 @@ public void Compare_inherited_double_nested_return_method()
Assert.IsTrue(mc.Equals(typeof(Base).GetMethod("GenericMethod7"),
typeof(Inherited).GetMethod("GenericMethod7")));
}

[Test]
public void Compare_two_method_overloads_with_generic_arg_types()
{
var mc = MethodSignatureComparer.Instance;
var methods = typeof(IHaveOverloadedGenericMethod).GetMethods();
var firstOverload = methods[0];
var secondOverload = methods[1];

// The overloads must obviously have different signatures, or we could never even have
// compiled this test code successfully. The arguments must have a different type:
Assert.IsFalse(mc.Equals(firstOverload, secondOverload));
}

private interface IHaveOverloadedGenericMethod
{
void GenericMethod<T>(GenericClass1<T> arg);
void GenericMethod<T>(GenericClass2<T> arg);
}

private class GenericClass1<T> { }

private class GenericClass2<T> { }
}
}
23 changes: 19 additions & 4 deletions src/Castle.Core/DynamicProxy/Generators/MethodSignatureComparer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -79,20 +79,35 @@ public bool EqualParameters(MethodInfo x, MethodInfo y)

public bool EqualSignatureTypes(Type x, Type y)
{
if (x.GetTypeInfo().IsGenericParameter != y.GetTypeInfo().IsGenericParameter)
var xti = x.GetTypeInfo();
var yti = y.GetTypeInfo();

if (xti.IsGenericParameter != yti.IsGenericParameter)
{
return false;
}
else if (xti.IsGenericType != yti.IsGenericType)
{
return false;
}

if (x.GetTypeInfo().IsGenericParameter)
if (xti.IsGenericParameter)
{
if (x.GetTypeInfo().GenericParameterPosition != y.GetTypeInfo().GenericParameterPosition)
if (xti.GenericParameterPosition != yti.GenericParameterPosition)
{
return false;
}
}
else if (x.GetTypeInfo().IsGenericType)
else if (xti.IsGenericType)
{
var xGenericTypeDef = xti.GetGenericTypeDefinition();
var yGenericTypeDef = yti.GetGenericTypeDefinition();

if (xGenericTypeDef != yGenericTypeDef)
{
return false;
}

var xArgs = x.GetGenericArguments();
var yArgs = y.GetGenericArguments();

Expand Down

0 comments on commit 26ad75d

Please sign in to comment.