Skip to content

Commit f937cc1

Browse files
authored
Optimize & document InterfaceMembersOnClassCollector (castleproject#667)
* Inline `IsVirtuallyImplementedInterfaceMethod` * Remove redundant call to `GetMethodOnTarget` * Add explanation for the `onlyProxyVirtual` flag
1 parent 222b1b8 commit f937cc1

File tree

1 file changed

+27
-10
lines changed

1 file changed

+27
-10
lines changed

src/Castle.Core/DynamicProxy/Contributors/InterfaceMembersOnClassCollector.cs

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,35 @@ public InterfaceMembersOnClassCollector(Type type, bool onlyProxyVirtual, Interf
3232

3333
protected override MetaMethod GetMethodToGenerate(MethodInfo method, IProxyGenerationHook hook, bool isStandalone)
3434
{
35-
if (onlyProxyVirtual && IsVirtuallyImplementedInterfaceMethod(method))
35+
var methodOnTarget = GetMethodOnTarget(method);
36+
37+
if (onlyProxyVirtual)
3638
{
37-
return null;
38-
}
39+
// The (somewhat confusingly named) `onlyProxyVirtual` flag may need some explaining.
40+
//
41+
// This collector type is used in two distinct scenarios:
42+
//
43+
// 1. When generating a class proxy for some class `T` which implements interface `I`,
44+
// and `I` is again specified as an additional interface to add to the proxy type.
45+
// In this case, this collector gets invoked for `I` and `onlyProxyVirtual == true`,
46+
// and below logic prevents `I` methods from being implemented a second time when
47+
// the main "target" contributor already took care of them (which happens when they
48+
// are overridable, or more specifically, when they are implicitly implemented and
49+
// marked as `virtual`).
50+
//
51+
// 2. When generating an interface proxy with target for some interface `I` and target
52+
// type `T`. In this case, `onlyProxyVirtual == false`, which forces members of `I`
53+
// to get implemented. Unlike in (1), the target of such proxies will be separate
54+
// objects, so it doesn't matter if & how they implement members of `I` or not;
55+
// those `I` members still need to be implemented on the proxy type regardless.
3956

40-
var methodOnTarget = GetMethodOnTarget(method);
57+
var isVirtuallyImplementedInterfaceMethod = methodOnTarget != null && methodOnTarget.IsFinal == false;
58+
59+
if (isVirtuallyImplementedInterfaceMethod)
60+
{
61+
return null;
62+
}
63+
}
4164

4265
var proxyable = AcceptMethod(method, onlyProxyVirtual, hook);
4366
return new MetaMethod(method, methodOnTarget, isStandalone, proxyable, methodOnTarget.IsPrivate == false);
@@ -53,11 +76,5 @@ private MethodInfo GetMethodOnTarget(MethodInfo method)
5376

5477
return map.TargetMethods[index];
5578
}
56-
57-
private bool IsVirtuallyImplementedInterfaceMethod(MethodInfo method)
58-
{
59-
var info = GetMethodOnTarget(method);
60-
return info != null && info.IsFinal == false;
61-
}
6279
}
6380
}

0 commit comments

Comments
 (0)