Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Nullable Value Tuples issue [duplicate]

I'm trying to update my code to use the new value tuples, and overall it's making it a lot more readable, so I love it.

However, I've ran into issues working with nullable values. In particular I have either collection entries that have to be null or functions that return null values under certain conditions. For example:

internal static TValue SafeTryGet<TKey, TValue>(this IDictionary<TKey, TValue> list, TKey key) =>
        list.TryGetValue(key, out TValue ret) ? ret : default(TValue);

This works fine with normal Tuple<> objects since they're classes, but value types will never return null which breaks this.

I've tried something like the below, but overloading resolution doesn't account for this case, it just gives a compilation error:

internal static TValue SafeTryGet<TKey, TValue>(this IDictionary<TKey, TValue> list, TKey key) where TValue : class =>
        list.TryGetValue(key, out TValue ret) ? ret : default(TValue);

internal static TValue? SafeTryGet<TKey, TValue>(this IDictionary<TKey, TValue> list, TKey key) where TValue : struct =>
        list.TryGetValue(key, out TValue ret) ? ret : new TValue?();

Short of providing a new method that does this, is there a clean way of writing this to return a nullable type when TValue is a struct? I emphasize the word clean because I can obviously code around it, but I'd like a semantic solution to the issue rather than a brute force approach.

Keep in mind that the same issue happens with the FirstOrDefault() Linq method. It won't return null, which makes it rather useless in this context. I'd like a solution that addresses this too if possible.

Edit: Please keep in mind the Linq issue. This is not a duplicate of that other post, because their requirements were more flexible. I'd like to make Linq work with value tuples as normal if possible.

like image 659
Blindy Avatar asked Sep 26 '26 18:09

Blindy


1 Answers

As for the link issue, that is easily solved:

IEnumerable<int> values = ...

int? fod = values.Select(i => (int?)i).FirstOrDefault();

Note that this not only works for IEnumerable<T>, but also for IQueryable<T>.

As for the more general quesion, that is indeed answered by Generic constraints, where T : struct and where T : class

like image 56
Kris Vandermotten Avatar answered Sep 28 '26 10:09

Kris Vandermotten