Skip to content

Commit

Permalink
Simplify delegate type check
Browse files Browse the repository at this point in the history
...and standardize on using `Delegate` instead of `MulticastDelegate`
in public method signatures. (This might seem contradictory, since the
delegate type check is based on the latter. But it will arguably cause
users less confusion to see `Delegate` than the less familiar `Multi-
castDelegate`. Also, BCL APIs such `Delegate.CreateDelegate` have a
declared return type of `Delegate`. Let's do the same.)
  • Loading branch information
stakx committed Mar 29, 2019
1 parent 6b37302 commit fcf6c63
Show file tree
Hide file tree
Showing 9 changed files with 28 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ private bool VerifyIfBaseImplementsGetObjectData(Type baseType, IList<MethodInfo
return false;
}

if (IsDelegate(baseType))
if (baseType.IsDelegateType())
{
//working around bug in CLR which returns true for "does this type implement ISerializable" for delegates
return false;
Expand Down Expand Up @@ -229,11 +229,6 @@ private bool VerifyIfBaseImplementsGetObjectData(Type baseType, IList<MethodInfo

return true;
}

private bool IsDelegate(Type baseType)
{
return baseType.BaseType == typeof(MulticastDelegate);
}
#endif
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ public virtual void Generate(ClassEmitter @class, ProxyGenerationOptions options
public void AddInterfaceToProxy(Type @interface)
{
Debug.Assert(@interface != null, "@interface == null", "Shouldn't be adding empty interfaces...");
Debug.Assert(@interface.GetTypeInfo().IsInterface || @interface.GetTypeInfo().IsSubclassOf(typeof(MulticastDelegate)), "@interface.IsInterface || @interface.IsSubclassOf(typeof(MulticastDelegate))", "Should be adding interfaces or delegate types only...");
Debug.Assert(@interface.GetTypeInfo().IsInterface || @interface.IsDelegateType(), "@interface.IsInterface || @interface.IsDelegateType()", "Should be adding interfaces or delegate types only...");
Debug.Assert(!interfaces.Contains(@interface), "!interfaces.ContainsKey(@interface)",
"Shouldn't be adding same interface twice...");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ namespace Castle.DynamicProxy.Contributors
using System.Reflection;

using Castle.DynamicProxy.Generators;
using Castle.DynamicProxy.Internal;

internal sealed class DelegateTypeMembersCollector : MembersCollector
{
Expand All @@ -28,7 +29,7 @@ public DelegateTypeMembersCollector(Type delegateType)

protected override MetaMethod GetMethodToGenerate(MethodInfo method, IProxyGenerationHook hook, bool isStandalone)
{
if (method.Name == "Invoke" && method.DeclaringType.GetTypeInfo().IsSubclassOf(typeof(MulticastDelegate)))
if (method.Name == "Invoke" && method.DeclaringType.IsDelegateType())
{
return new MetaMethod(method, method, isStandalone, true, false);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ namespace Castle.DynamicProxy.Contributors
using Castle.DynamicProxy.Generators;
using Castle.DynamicProxy.Generators.Emitters;
using Castle.DynamicProxy.Generators.Emitters.SimpleAST;
using Castle.DynamicProxy.Internal;

public class MixinContributor : CompositeTypeContributor
{
Expand Down Expand Up @@ -79,7 +80,7 @@ protected override IEnumerable<MembersCollector> CollectElementsToProxyInternal(
}
else
{
Debug.Assert(@interface.GetTypeInfo().IsSubclassOf(typeof(MulticastDelegate)));
Debug.Assert(@interface.IsDelegateType());
item = new DelegateTypeMembersCollector(@interface);
}
item.CollectMembersToProxy(hook);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ namespace Castle.DynamicProxy.Generators.Emitters
using System.Reflection;
using System.Reflection.Emit;

using Castle.DynamicProxy.Internal;

public class ClassEmitter : AbstractTypeEmitter
{
internal const TypeAttributes DefaultAttributes =
Expand Down Expand Up @@ -55,7 +57,7 @@ public ClassEmitter(ModuleScope modulescope, String name, Type baseType, IEnumer
}
else
{
Debug.Assert(inter.GetTypeInfo().IsSubclassOf(typeof(MulticastDelegate)));
Debug.Assert(inter.IsDelegateType());
}
}
}
Expand Down
8 changes: 8 additions & 0 deletions src/Castle.Core/DynamicProxy/Internal/TypeUtil.cs
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,14 @@ public static MemberInfo[] Sort(MemberInfo[] members)
return sortedMembers;
}

/// <summary>
/// Checks whether the specified <paramref name="type"/> is a delegate type (i.e. a direct subclass of <see cref="MulticastDelegate"/>).
/// </summary>
internal static bool IsDelegateType(this Type type)
{
return type.GetTypeInfo().BaseType == typeof(MulticastDelegate);
}

private static bool CloseGenericParametersIfAny(AbstractTypeEmitter emitter, Type[] arguments)
{
var hasAnyGenericParameters = false;
Expand Down
11 changes: 6 additions & 5 deletions src/Castle.Core/DynamicProxy/MixinData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ namespace Castle.DynamicProxy
using System.Reflection;

using Castle.DynamicProxy.Generators;
using Castle.DynamicProxy.Internal;

public class MixinData
{
Expand Down Expand Up @@ -55,7 +56,7 @@ public MixinData(IEnumerable<object> mixinInstances)
mixinInterfaces = new[] { mixin.GetType() };
target = mixin;
}
else if (mixin is Type delegateType && delegateType.GetTypeInfo().IsSubclassOf(typeof(MulticastDelegate)))
else if (mixin is Type delegateType && delegateType.IsDelegateType())
{
++delegateMixinCount;
mixinInterfaces = new[] { delegateType };
Expand Down Expand Up @@ -84,7 +85,7 @@ public MixinData(IEnumerable<object> mixinInstances)
}
else
{
Debug.Assert(inter.GetTypeInfo().IsSubclassOf(typeof(MulticastDelegate)));
Debug.Assert(inter.IsDelegateType());
message = string.Format(
"The list of mixins already contains a mixin for delegate type '{0}'.",
inter.FullName);
Expand All @@ -102,7 +103,7 @@ public MixinData(IEnumerable<object> mixinInstances)
var invokeMethods = new HashSet<MethodInfo>();
foreach (var mixedInType in interface2Mixin.Keys)
{
if (mixedInType.GetTypeInfo().IsSubclassOf(typeof(MulticastDelegate)))
if (mixedInType.IsDelegateType())
{
var invokeMethod = mixedInType.GetMethod("Invoke");
if (invokeMethods.Contains(invokeMethod, MethodSignatureComparer.Instance))
Expand Down Expand Up @@ -176,8 +177,8 @@ public override bool Equals(object obj)

if (delegateMixinCount > 0)
{
var delegateMixinTypes = mixinPositions.Select(m => m.Key).Where(t => t.GetTypeInfo().IsSubclassOf(typeof(MulticastDelegate)));
var otherDelegateMixinTypes = other.mixinPositions.Select(m => m.Key).Where(t => t.GetTypeInfo().IsSubclassOf(typeof(MulticastDelegate)));
var delegateMixinTypes = mixinPositions.Select(m => m.Key).Where(TypeUtil.IsDelegateType);
var otherDelegateMixinTypes = other.mixinPositions.Select(m => m.Key).Where(TypeUtil.IsDelegateType);
return Enumerable.SequenceEqual(delegateMixinTypes, otherDelegateMixinTypes);
}

Expand Down
5 changes: 3 additions & 2 deletions src/Castle.Core/DynamicProxy/ProxyGenerationOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ namespace Castle.DynamicProxy
#endif

using Castle.Core.Internal;
using Castle.DynamicProxy.Internal;

#if FEATURE_SERIALIZATION
[Serializable]
Expand Down Expand Up @@ -140,7 +141,7 @@ public void AddDelegateTypeMixin(Type delegateType)
throw new ArgumentNullException(nameof(delegateType));
}

if (delegateType.GetTypeInfo().IsSubclassOf(typeof(MulticastDelegate)) == false)
if (!delegateType.IsDelegateType())
{
throw new ArgumentException("Type must be a delegate type.", nameof(delegateType));
}
Expand All @@ -155,7 +156,7 @@ public void AddDelegateTypeMixin(Type delegateType)
/// </summary>
/// <param name="delegate">The delegate that should act as the target for calls to `Invoke` methods with a matching signature.</param>
/// <exception cref="ArgumentNullException"><paramref name="delegate"/> is <see langword="null"/>.</exception>
public void AddDelegateMixin(MulticastDelegate @delegate)
public void AddDelegateMixin(Delegate @delegate)
{
if (@delegate == null)
{
Expand Down
3 changes: 2 additions & 1 deletion src/Castle.Core/DynamicProxy/ProxyUtil.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ namespace Castle.DynamicProxy

using Castle.Core.Internal;
using Castle.DynamicProxy.Generators;
using Castle.DynamicProxy.Internal;

public static class ProxyUtil
{
Expand Down Expand Up @@ -74,7 +75,7 @@ public static bool TryCreateDelegateToMixin(object proxy, Type delegateType, out
throw new ArgumentNullException(nameof(delegateType));
}

if (delegateType.GetTypeInfo().IsSubclassOf(typeof(MulticastDelegate)) == false)
if (!delegateType.IsDelegateType())
{
throw new ArgumentException("Type is not a delegate type.", nameof(delegateType));
}
Expand Down

0 comments on commit fcf6c63

Please sign in to comment.