How to return named tuples in C#?
32,137
Solution 1
Like this:
public (DateTime Start, DateTime End) DateRanges
{
get
{
return (DateTime.MinValue, DateTime.MaxValue);
}
}
Note: This requires a recent version of C# and .Net.
Incidentally, watch out for this usage pattern:
var from = filter?.DateRanges.Start;
var to = filter?.DateRanges.End;
That's inefficient because it causes two identical tuples to be created.
This is better:
var range = filter?.DateRanges;
if (range.HasValue)
{
var from = range.Value.Start;
var to = range.Value.End;
}
However note that tuples cannot be null (they are value types) so you could write it like so:
if (filter != null)
{
var range = filter.DateRanges;
var from = range.Start;
var to = range.End;
...
}
Solution 2
class Program
{
static void Main(string[] args)
{
test t = new test();
Console.WriteLine(t.NamedTuple.start);
Console.WriteLine(t.NamedTuple.stop);
Console.Read();
}
}
class test
{
DateTime From;
DateTime To;
public (DateTime start, DateTime stop) NamedTuple
{
get
{
From = DateTime.Now.AddDays(-1).Date.AddMonths(-1);
To = DateTime.Now.AddDays(-1).Date;
return (From, To);
}
}
}
Author by
Karim Ali
Updated on August 04, 2020Comments
-
Karim Ali almost 4 years
I have a property that returns two items of type
DateTime
. When returning these values I have to reference them asItem1
andItem2
. How do I return with custom names e.g.filter?.DateRanges.From filter?.DateRanges.To
public Tuple<DateTime, DateTime> DateRanges { get { From = DateTime.Now.AddDays(-1).Date.AddMonths(-1); To = DateTime.Now.AddDays(-1).Date; if (Preset != 0) { if (Preset == DatePreset.SpecificRange) { From = From.Date; To = To.Date; } else { var dateRange = DateTime.Today.AddDays(-1).GetDateRangeByPreset(Preset); From = dateRange.From; To = dateRange.To; } } return new Tuple<DateTime, DateTime>(From, To); }
usage:
var from = filter?.DateRanges.Item1; var to = filter?.DateRanges.Item2;
-
JasperMoneyshot almost 6 yearsPossible duplicate of Better naming in Tuple classes than "Item1", "Item2"
-
Rui Jarimba almost 6 yearsAFAIK there is no such thing as "named tuples". The alternative is to create a custom class with the property names you want
-
Jon Skeet almost 6 years@RuiJarimba: There are definitely C# tuples with named elements, as of C# 7. They use
ValueTuple<>
rather thanTuple<>
though. -
Rui Jarimba almost 6 yearsOh that's nice, I wasn't aware of that new feature. Thanks @DaisyShipton
-
-
Karim Ali almost 6 yearsstrangely your second method does not work, var range = filter?.DateRanges; range variable doesn't allow Start and End
-
Matthew Watson almost 6 years@KarimAli Ah, that's because it's a nullable (with the
?
) so I should have been using.Value
. I've edited my answer. But actually it's pointless using a nullable here because tuples CANNOT be null. -
John Stock over 4 yearsThis is not what was asked. Your answer is more than a syntax difference, it's a valuetype not reference which the Tuple<> syntax.
-
Matthew Watson over 4 years@JohnStock I pointed out that it's a value type in my answer where I said
(they are value types)
, so the fact that they are value types should be a surprise to no-one. I even bolded the part where I saidtuples cannot be null
. -
Dave Black almost 4 years@MatthewWatson I appreciate you pointing out how the code can be misused (made less efficient) by calling the
DateRanges
method twice thereby creating 2 tuples. And furthermore providing a better "usage" recommendation. While the fact you are creating 2 tuples is somewhat obvious by inspection, it can be easily missed - especially when you are using code written by someone else!