Skip to content

Commit eda2c80

Browse files
committed
Move check for covariant return types
Performing this check for anything other than return types is basically wasted time, so moving it to `EqualReturnTypes` means it will only run when actually needed.
1 parent a1b44d7 commit eda2c80

File tree

1 file changed

+23
-27
lines changed

1 file changed

+23
-27
lines changed

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

Lines changed: 23 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ namespace Castle.DynamicProxy.Generators
1616
{
1717
using System;
1818
using System.Collections.Generic;
19-
using System.Diagnostics;
2019
using System.Reflection;
2120

2221
internal class MethodSignatureComparer : IEqualityComparer<MethodInfo>
@@ -82,18 +81,35 @@ public bool EqualParameters(MethodInfo x, MethodInfo y)
8281

8382
public bool EqualReturnTypes(MethodInfo x, MethodInfo y)
8483
{
85-
return EqualSignatureTypes(x.ReturnType, y.ReturnType, x, y);
84+
var xr = x.ReturnType;
85+
var yr = y.ReturnType;
86+
87+
if (EqualSignatureTypes(xr, yr))
88+
{
89+
return true;
90+
}
91+
92+
// This enables covariant method returns for .NET 5 and newer.
93+
// No need to check for runtime support, since such methods are marked with a custom attribute;
94+
// see https://github.com/dotnet/runtime/blob/main/docs/design/features/covariant-return-methods.md.
95+
if (preserveBaseOverridesAttribute != null)
96+
{
97+
return (x.IsDefined(preserveBaseOverridesAttribute, inherit: false) && yr.IsAssignableFrom(xr))
98+
|| (y.IsDefined(preserveBaseOverridesAttribute, inherit: false) && xr.IsAssignableFrom(yr));
99+
}
100+
101+
return false;
86102
}
87103

88-
private bool EqualSignatureTypes(Type x, Type y, MethodInfo xm = null, MethodInfo ym = null)
104+
private bool EqualSignatureTypes(Type x, Type y)
89105
{
90106
if (x.IsGenericParameter != y.IsGenericParameter)
91107
{
92108
return false;
93109
}
94110
else if (x.IsGenericType != y.IsGenericType)
95111
{
96-
return IsCovariantReturnTypes(x, y, xm, ym);
112+
return false;
97113
}
98114

99115
if (x.IsGenericParameter)
@@ -121,39 +137,19 @@ private bool EqualSignatureTypes(Type x, Type y, MethodInfo xm = null, MethodInf
121137
return false;
122138
}
123139

124-
if (IsCovariantReturnTypes(x, y, xm, ym) == false)
140+
for (var i = 0; i < xArgs.Length; ++i)
125141
{
126-
for (var i = 0; i < xArgs.Length; ++i)
127-
{
128-
if(!EqualSignatureTypes(xArgs[i], yArgs[i])) return false;
129-
}
142+
if(!EqualSignatureTypes(xArgs[i], yArgs[i])) return false;
130143
}
131144
}
132145
else
133146
{
134147
if (!x.Equals(y))
135148
{
136-
return IsCovariantReturnTypes(x, y, xm, ym);
149+
return false;
137150
}
138151
}
139152
return true;
140-
141-
static bool IsCovariantReturnTypes(Type x, Type y, MethodInfo xm, MethodInfo ym)
142-
{
143-
Debug.Assert((xm == null && ym == null)
144-
|| (xm != null && ym != null && x == xm.ReturnType && y == ym.ReturnType));
145-
146-
// This enables covariant method returns for .NET 5 and newer.
147-
// No need to check for runtime support, since such methods are marked with a custom attribute;
148-
// see https://github.com/dotnet/runtime/blob/main/docs/design/features/covariant-return-methods.md.
149-
if (preserveBaseOverridesAttribute != null)
150-
{
151-
return (xm != null && xm.IsDefined(preserveBaseOverridesAttribute, inherit: false) && y.IsAssignableFrom(x))
152-
|| (ym != null && ym.IsDefined(preserveBaseOverridesAttribute, inherit: false) && x.IsAssignableFrom(y));
153-
}
154-
155-
return false;
156-
}
157153
}
158154

159155
public bool Equals(MethodInfo x, MethodInfo y)

0 commit comments

Comments
 (0)