网上演练
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

141 lines
4.1 KiB

// Needed for Workaround
#if !NET_4_6
using System;
using System.Reflection.Extensions;
using LinqInternal.Core;
using MethodInfo = System.Reflection.MethodInfo;
namespace LinqInternal.Threading.Needles
{
[System.Diagnostics.DebuggerNonUserCode]
internal sealed class WeakDelegateNeedle : WeakNeedle<Delegate>, IEquatable<Delegate>, IEquatable<WeakDelegateNeedle>
{
public WeakDelegateNeedle(Delegate handler)
: base(Check.NotNullArgument(handler, "handler"))
{
if (handler == null)
{
throw new ArgumentNullException("handler");
}
//var temp = handler;
}
public WeakDelegateNeedle(MethodInfo methodInfo, object target)
: base(BuildDelegate(methodInfo, target))
{
// Empty
}
public MethodInfo Method
{
get
{
var value = Value;
if (IsAlive)
{
return value.GetMethodInfo();
}
return null;
}
}
public bool Equals(Delegate other)
{
var method = other.GetMethodInfo();
return !ReferenceEquals(null, other) && Equals(method, other.Target);
}
public bool Equals(MethodInfo method, object target)
{
var value = Value;
if (IsAlive)
{
return value.GetMethodInfo().Equals(method) && ReferenceEquals(value.Target, target);
}
return false;
}
public bool Equals(WeakDelegateNeedle other)
{
if (ReferenceEquals(null, other))
{
return false;
}
var value = Value;
if (IsAlive)
{
var otherValue = other.Value;
if (other.IsAlive)
{
var method = otherValue.GetMethodInfo();
return value.GetMethodInfo().Equals(method) && ReferenceEquals(value.Target, otherValue.Target);
}
return false;
}
return !other.IsAlive;
}
public void Invoke(object[] args)
{
TryInvoke(args);
}
public bool TryInvoke(object[] args)
{
var value = Value;
if (IsAlive)
{
value.DynamicInvoke(args); // Throws TargetInvocationException
return true;
}
return false;
}
public bool TryInvoke(object[] args, out object result)
{
var value = Value;
if (IsAlive)
{
result = value.DynamicInvoke(args);
return true;
}
result = null;
return false;
}
public bool TryInvoke<TResult>(object[] args, out TResult result)
{
var value = Value;
if (IsAlive)
{
result = (TResult)value.DynamicInvoke(args);
return true;
}
result = default(TResult);
return false;
}
private static Delegate BuildDelegate(MethodInfo methodInfo, object target)
{
if (ReferenceEquals(methodInfo, null))
{
throw new ArgumentNullException("methodInfo");
}
if (methodInfo.IsStatic != ReferenceEquals(null, target))
{
if (ReferenceEquals(target, null))
{
throw new ArgumentNullException("target", "target is null and the method is not static.");
}
throw new ArgumentException("target is not null and the method is static", "target");
}
var type = methodInfo.DeclaringType;
if (ReferenceEquals(type, null))
{
throw new ArgumentException("methodInfo.DeclaringType is null", "methodInfo");
}
return methodInfo.CreateDelegate(type, target);
}
}
}
#endif