Just to add to @MichaelMocko answer. Tuples have couple of gotchas at the moment:
Example:
public static (string name, string surname) GetPersonName(this PersonContext ctx, int id)
{
return ctx.Persons
.Where(person => person.Id == id)
// Selecting as Tuple
.Select(person => (person.Name, person.Surname))
.First();
}
This will fail to compile with "An expression tree may not contain a tuple literal" error. Unfortunately, the expression trees API wasn't expanded with support for tuples when these were added to the language.
Track (and upvote) this issue for the updates: https://github.com/dotnet/roslyn/issues/12897
To get around the problem, you can cast it to anonymous type first and then convert the value to tuple:
// Will work
public static (string name, string surname) GetPersonName(this PersonContext ctx, int id)
{
return ctx.Persons
.Where(person => person.Id == id)
.Select(person => new { person.Name, person.Surname })
.ToList()
.Select(person => (person.Name, person.Surname))
.First();
}
Another option is to use ValueTuple.Create:
// Will work
public static (string name, string surname) GetPersonName(this PersonContext ctx, int id)
{
return ctx.Persons
.Where(person => person.Id == id)
.Select(person => ValueTuple.Create(person.Name, person.Surname))
.First();
}
References:
There's a proposal to add the support: https://github.com/dotnet/csharplang/issues/258
Example:
public static IQueryable<(string name, string surname)> GetPersonName(this PersonContext ctx, int id)
{
return ctx.Persons
.Where(person => person.Id == id)
.Select(person => ValueTuple.Create(person.Name, person.Surname));
}
// This won't work
ctx.GetPersonName(id).Select((name, surname) => { return name + surname; })
// But this will
ctx.GetPersonName(id).Select(t => { return t.name + t.surname; })
References:
using System;
using Newtonsoft.Json;
public class Program
{
public static void Main() {
var me = (age: 21, favoriteFood: "Custard");
string json = JsonConvert.SerializeObject(me);
// Will output {"Item1":21,"Item2":"Custard"}
Console.WriteLine(json);
}
}
Tuple field names are only available at compile time and are completely wiped out at runtime.
References: