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.
113 lines
3.0 KiB
113 lines
3.0 KiB
5 years ago
|
// Needed for NET35 (ThreadLocal)
|
||
|
#if !NET_4_6
|
||
|
using System;
|
||
|
using System.Collections.Generic;
|
||
|
|
||
|
namespace LinqInternal.Threading.Needles
|
||
|
{
|
||
|
[Serializable]
|
||
|
[System.Diagnostics.DebuggerNonUserCode]
|
||
|
internal struct ReadOnlyStructNeedle<T> : INeedle<T>, IEquatable<ReadOnlyStructNeedle<T>>
|
||
|
{
|
||
|
private readonly T _value;
|
||
|
|
||
|
public ReadOnlyStructNeedle(T target)
|
||
|
{
|
||
|
_value = target;
|
||
|
}
|
||
|
|
||
|
T INeedle<T>.Value
|
||
|
{
|
||
|
get { return _value; }
|
||
|
|
||
|
set { throw new NotSupportedException(); }
|
||
|
}
|
||
|
|
||
|
public bool IsAlive
|
||
|
{
|
||
|
get { return !ReferenceEquals(_value, null); }
|
||
|
}
|
||
|
|
||
|
public T Value
|
||
|
{
|
||
|
get { return _value; }
|
||
|
}
|
||
|
|
||
|
public static explicit operator T(ReadOnlyStructNeedle<T> needle)
|
||
|
{
|
||
|
return needle._value;
|
||
|
}
|
||
|
|
||
|
public static implicit operator ReadOnlyStructNeedle<T>(T field)
|
||
|
{
|
||
|
return new ReadOnlyStructNeedle<T>(field);
|
||
|
}
|
||
|
|
||
|
public static bool operator !=(ReadOnlyStructNeedle<T> left, ReadOnlyStructNeedle<T> right)
|
||
|
{
|
||
|
return NotEqualsExtracted(left, right);
|
||
|
}
|
||
|
|
||
|
public static bool operator ==(ReadOnlyStructNeedle<T> left, ReadOnlyStructNeedle<T> right)
|
||
|
{
|
||
|
return EqualsExtracted(left, right);
|
||
|
}
|
||
|
|
||
|
public override bool Equals(object obj)
|
||
|
{
|
||
|
if (obj is ReadOnlyStructNeedle<T>)
|
||
|
{
|
||
|
return EqualsExtracted(this, (ReadOnlyStructNeedle<T>)obj);
|
||
|
}
|
||
|
// Keep the "is" operator
|
||
|
if (obj is T)
|
||
|
{
|
||
|
var target = _value;
|
||
|
return IsAlive && EqualityComparer<T>.Default.Equals(target, (T)obj);
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
public bool Equals(ReadOnlyStructNeedle<T> other)
|
||
|
{
|
||
|
return EqualsExtracted(this, other);
|
||
|
}
|
||
|
|
||
|
public override int GetHashCode()
|
||
|
{
|
||
|
return base.GetHashCode();
|
||
|
}
|
||
|
|
||
|
public override string ToString()
|
||
|
{
|
||
|
if (IsAlive)
|
||
|
{
|
||
|
return _value.ToString();
|
||
|
}
|
||
|
return "<Dead Needle>";
|
||
|
}
|
||
|
|
||
|
private static bool EqualsExtracted(ReadOnlyStructNeedle<T> left, ReadOnlyStructNeedle<T> right)
|
||
|
{
|
||
|
var leftValue = left._value;
|
||
|
if (left.IsAlive)
|
||
|
{
|
||
|
var rightValue = right._value;
|
||
|
return right.IsAlive && EqualityComparer<T>.Default.Equals(leftValue, rightValue);
|
||
|
}
|
||
|
return !right.IsAlive;
|
||
|
}
|
||
|
|
||
|
private static bool NotEqualsExtracted(ReadOnlyStructNeedle<T> left, ReadOnlyStructNeedle<T> right)
|
||
|
{
|
||
|
var leftValue = left._value;
|
||
|
if (left.IsAlive)
|
||
|
{
|
||
|
var rightValue = right._value;
|
||
|
return !right.IsAlive || !EqualityComparer<T>.Default.Equals(leftValue, rightValue);
|
||
|
}
|
||
|
return right.IsAlive;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
#endif
|