public static class X { /// Easy with structs</remarks public static bool TryGetValue(this T? nullable, ref T value) where T : struct { if (nullable.HasValue) { value = nullable.Value; return true; }
return false;
}
/// <remarks>Maybe with _defaultable_ types?</remarks
public static bool TryGetValue<T>(this T? nullable, out T value) where T : class, IDefaulted<T>, new()
{
if (nullable is not null)
{
value = nullable;
return true;
}
value = IDefaulted<T>.Default;
return false;
}
/// <remarks>Can't not set out parameter without throwing something :(</remarks
//public static bool TryGetValue<T>(this T? nullable, out T value) where T : class
//{
// if (nullable is not null)
// {
// value = nullable;
// return true;
// }
// throw new NullReferenceException();
//}
/// <remarks>Maybe _lazily_ via a getter?</remarks
public static bool TryGetValueGetter<T>(this T? nullable, out Func<T> getter)
{
if (nullable is not null)
{
getter = () => nullable;
return true;
}
getter = () => throw new InvalidOperationException("You peeked at Schrödinger's cat!");
return false;
}
/// <remarks>Maybe _explicitly lazily_ via Lazy<T></remarks>>
public static bool TryGetLazyValue<T>(this T? nullable, out Lazy<T> lazy)
{
if (nullable is not null)
{
lazy = new Lazy<T>(nullable);
return true;
}
lazy = new Lazy<T>(()=>throw new InvalidOperationException("You peeked at Schrödinger's cat!"));
return false;
}
}
public interface IDefaulted where T : class, new() { public static T Default { get; } = new T(); }