I was coding some tooling stuff when I started to ponder whether the best return type for a Range / MinMax method applied on a IEnumerable method.
I am using the value the C# 7 Tuples like below, but tempted to create my own class with readonly fields.
public static (TSource Min, TSource Max) MinMax<TSource>(this IEnumerable<TSource> source, IComparer<TSource> comparer)
{
using (var sourceIterator = source.GetEnumerator())
{
if (!sourceIterator.MoveNext())
{
throw new InvalidOperationException("Sequence contains no elements");
}
var max = sourceIterator.Current;
var min = sourceIterator.Current;
while (sourceIterator.MoveNext())
{
var candidate = sourceIterator.Current;
if (comparer.LeftStrictlyLesserThanRight(candidate, min))
{
min = candidate;
}
if (comparer.LeftStrictlyGreaterThanRight(candidate, max))
{
max = candidate;
}
}
return (min, max);
}
}
Utilities are defined as below:
internal static class ComparerExtensions
{
public static bool LeftStrictlyGreaterThanRight<T>(this IComparer<T> comparer, T left, T right)
{
return comparer.Compare(left, right) > 0;
}
public static bool LeftStrictlyLesserThanRight<T>(this IComparer<T> comparer, T left, T right)
{
return comparer.Compare(left, right) < 0;
}
}
What do you think is the best, knowing that creating a reference type would bring some additional allocations and GC work (I mean that was the whole point to have struct-like tuples in C# 7). What bothers me with the tuple is that fields are not readonly and we cannot prevent users of the method to mess up and break flow.
I don't know maybe it's just me and my over-defensive coding style and bad experience using Python where coders are considered as "adults"?
LeftStrictlyLesserThanRight
- I think virtually all programming languages call this just less-than and its counterpart less-than-or-equal. \$\endgroup\$