// Needed for NET40 #if !NET_4_6 using System; using System.Collections.Generic; namespace LinqInternal.Threading.Needles { [Serializable] [System.Diagnostics.DebuggerNonUserCode] internal struct StructNeedle : IEquatable>, IRecyclableNeedle { private T _value; public StructNeedle(T target) { _value = target; } public bool IsAlive { get { return !ReferenceEquals(Value, null); } } public T Value { get { // Keep backing field return _value; } set { // Keep backing field _value = value; } } public static explicit operator T(StructNeedle needle) { return needle.Value; } public static implicit operator StructNeedle(T field) { return new StructNeedle(field); } public static bool operator !=(StructNeedle left, StructNeedle right) { return NotEqualsExtracted(left, right); } public static bool operator ==(StructNeedle left, StructNeedle right) { return EqualsExtracted(left, right); } public override bool Equals(object obj) { if (obj is StructNeedle) { return EqualsExtracted(this, (StructNeedle)obj); } // Keep the "is" operator if (obj is T) { var target = Value; return IsAlive && EqualityComparer.Default.Equals(target, (T)obj); } return false; } public bool Equals(StructNeedle other) { return EqualsExtracted(this, other); } public override int GetHashCode() { return base.GetHashCode(); } void IRecyclableNeedle.Free() { Value = default(T); } public override string ToString() { var target = Value; if (IsAlive) { return target.ToString(); } return ""; } private static bool EqualsExtracted(StructNeedle left, StructNeedle right) { var leftValue = left.Value; if (left.IsAlive) { var rightValue = right.Value; return right.IsAlive && EqualityComparer.Default.Equals(leftValue, rightValue); } return !right.IsAlive; } private static bool NotEqualsExtracted(StructNeedle left, StructNeedle right) { var leftValue = left.Value; if (left.IsAlive) { var rightValue = right.Value; return !right.IsAlive || !EqualityComparer.Default.Equals(leftValue, rightValue); } return right.IsAlive; } } } #endif