Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to return named tuples in C#?

I have a property that returns two items of type DateTime. When returning these values I have to reference them as Item1 and Item2. 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;
like image 865
Karim Ali Avatar asked Aug 03 '18 10:08

Karim Ali


People also ask

How do you name a tuple?

Creating a Named Tuple To create a named tuple, import the namedtuple class from the collections module. The constructor takes the name of the named tuple (which is what type() will report), and a string containing the fields names, separated by whitespace. It returns a new namedtuple class for the specified fields.

Can you name a tuple in C#?

Starting C# v7. 0, it is now possible to name the tuple properties which earlier used to default to names like Item1 , Item2 and so on.

Is tuple reference type?

Tuple types are reference types. System. ValueTuple types are mutable.

Can tuple be null?

ValueTuple is the underlying type used for the C#7 tuples. They cannot be null as they are value types.


2 Answers

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;
    ...
}

ADDENDUM (2022):

Nowadays you can much more simply assign the values of a tuple to local variables. Now we can rewrite the last example above like so:

if (filter != null)
{
    var (from, to) = filter.DateRanges;
    ...
}
like image 194
Matthew Watson Avatar answered Oct 09 '22 14:10

Matthew Watson


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);
        }

    }
}
like image 36
Kolkil Kolk Avatar answered Oct 09 '22 13:10

Kolkil Kolk