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
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 |