Skip to content

Commit 26ad75d

Browse files
stakxjonorossi
authored andcommitted
Add missing equality checks to MethodSignatureComparer.EqualSignatureTypes
1 parent 6fb2df5 commit 26ad75d

4 files changed

Lines changed: 68 additions & 4 deletions

File tree

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
# Castle Core Changelog
22

3+
## Unreleased
4+
5+
Bugfixes:
6+
- Add missing equality checks in `MethodSignatureComparer.EqualSignatureTypes` to fix `TypeLoadException`s ("Method does not have an implementation") (@stakx, #310)
7+
38
## 4.2.0 (2017-09-28)
49

510
Enhancements:

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

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,13 @@ public void NonVirtualExplicitInterfaceMethods_AreIgnored_OnClassProxy()
176176

177177
Assert.AreEqual(5, result);
178178
}
179+
180+
[Test]
181+
public void CreateClassProxy_GivenAdditionalInterfaceWithOverloadedGenericMethodsHavingGenericParameter_SuccessfullyCreatesProxyInstance()
182+
{
183+
var instance = generator.CreateClassProxy(typeof(object), new Type[] { typeof(InterfaceWithOverloadedGenericMethod) }, interceptor);
184+
Assert.NotNull(instance);
185+
}
179186
}
180187

181188
public class ExplicitInterfaceWithPropertyImplementation : ISimpleInterfaceWithProperty
@@ -185,4 +192,18 @@ public int Age
185192
get { throw new NotImplementedException(); }
186193
}
187194
}
195+
196+
public interface InterfaceWithOverloadedGenericMethod
197+
{
198+
void GenericMethod<T>(GenericClass1<T> arg);
199+
void GenericMethod<T>(GenericClass2<T> arg);
200+
}
201+
202+
public class GenericClass1<T>
203+
{
204+
}
205+
206+
public class GenericClass2<T>
207+
{
208+
}
188209
}

src/Castle.Core.Tests/MethodComparerTestCase.cs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,5 +355,28 @@ public void Compare_inherited_double_nested_return_method()
355355
Assert.IsTrue(mc.Equals(typeof(Base).GetMethod("GenericMethod7"),
356356
typeof(Inherited).GetMethod("GenericMethod7")));
357357
}
358+
359+
[Test]
360+
public void Compare_two_method_overloads_with_generic_arg_types()
361+
{
362+
var mc = MethodSignatureComparer.Instance;
363+
var methods = typeof(IHaveOverloadedGenericMethod).GetMethods();
364+
var firstOverload = methods[0];
365+
var secondOverload = methods[1];
366+
367+
// The overloads must obviously have different signatures, or we could never even have
368+
// compiled this test code successfully. The arguments must have a different type:
369+
Assert.IsFalse(mc.Equals(firstOverload, secondOverload));
370+
}
371+
372+
private interface IHaveOverloadedGenericMethod
373+
{
374+
void GenericMethod<T>(GenericClass1<T> arg);
375+
void GenericMethod<T>(GenericClass2<T> arg);
376+
}
377+
378+
private class GenericClass1<T> { }
379+
380+
private class GenericClass2<T> { }
358381
}
359382
}

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

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -79,20 +79,35 @@ public bool EqualParameters(MethodInfo x, MethodInfo y)
7979

8080
public bool EqualSignatureTypes(Type x, Type y)
8181
{
82-
if (x.GetTypeInfo().IsGenericParameter != y.GetTypeInfo().IsGenericParameter)
82+
var xti = x.GetTypeInfo();
83+
var yti = y.GetTypeInfo();
84+
85+
if (xti.IsGenericParameter != yti.IsGenericParameter)
86+
{
87+
return false;
88+
}
89+
else if (xti.IsGenericType != yti.IsGenericType)
8390
{
8491
return false;
8592
}
8693

87-
if (x.GetTypeInfo().IsGenericParameter)
94+
if (xti.IsGenericParameter)
8895
{
89-
if (x.GetTypeInfo().GenericParameterPosition != y.GetTypeInfo().GenericParameterPosition)
96+
if (xti.GenericParameterPosition != yti.GenericParameterPosition)
9097
{
9198
return false;
9299
}
93100
}
94-
else if (x.GetTypeInfo().IsGenericType)
101+
else if (xti.IsGenericType)
95102
{
103+
var xGenericTypeDef = xti.GetGenericTypeDefinition();
104+
var yGenericTypeDef = yti.GetGenericTypeDefinition();
105+
106+
if (xGenericTypeDef != yGenericTypeDef)
107+
{
108+
return false;
109+
}
110+
96111
var xArgs = x.GetGenericArguments();
97112
var yArgs = y.GetGenericArguments();
98113

0 commit comments

Comments
 (0)