Created
November 12, 2019 07:50
-
-
Save jfrijters/b816f8100c0aa1cce8a2ddbc0c64fbac to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public readonly struct NullableDouble | |
{ | |
private readonly long value; | |
private NullableDouble(double value) | |
{ | |
var bits = BitConverter.DoubleToInt64Bits(value); | |
if (bits == -1) | |
{ | |
// the double passed in was NaN, but the pattern equals the pattern we use for NULL values, | |
// so we replace it with the canonical NaN value | |
bits = unchecked((long)0xFFF8000000000000); | |
} | |
this.value = ~bits; | |
} | |
private double InternalToDouble() => BitConverter.Int64BitsToDouble(~value); | |
public bool HasValue => value != 0; | |
public double Value | |
{ | |
get | |
{ | |
if (!HasValue) | |
{ | |
ThrowInvalidOperationException(); | |
} | |
return InternalToDouble(); | |
} | |
} | |
public double GetValueOrDefault() | |
{ | |
if (HasValue) | |
{ | |
return InternalToDouble(); | |
} | |
return 0; | |
} | |
public double GetValueOrDefault(double defaultValue) | |
{ | |
if (HasValue) | |
{ | |
return InternalToDouble(); | |
} | |
return defaultValue; | |
} | |
private static void ThrowInvalidOperationException() => throw new InvalidOperationException(); | |
public static implicit operator NullableDouble(double value) | |
{ | |
return new NullableDouble(value); | |
} | |
public static implicit operator NullableDouble(double? value) | |
{ | |
if (value.HasValue) | |
{ | |
return value.GetValueOrDefault(); | |
} | |
return default; | |
} | |
public static implicit operator double?(NullableDouble value) | |
{ | |
if (value.HasValue) | |
{ | |
return value.InternalToDouble(); | |
} | |
return null; | |
} | |
public static explicit operator double(NullableDouble value) | |
{ | |
return value.Value; | |
} | |
public override bool Equals(object obj) | |
{ | |
if (HasValue) | |
{ | |
return InternalToDouble().Equals(obj); | |
} | |
return obj == null; | |
} | |
public override int GetHashCode() | |
{ | |
if (HasValue) | |
{ | |
return InternalToDouble().GetHashCode(); | |
} | |
return 0; | |
} | |
public override string ToString() | |
{ | |
double? value = this; | |
return value.ToString(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment