Reputation: 1346
How and "could be" organized return from the method which returns tuple type with the name of parameters, as an example
private static Tuple<string, string> methodTuple()
{
return new {Name = "Nick", Age = "Twenty"}; /*exception because need to new Tuple<string, string>(){Item1 = "Nick", Item2 = "Twenty"}o*/
}
and call parameters like methodTuple.Name
not like methodTuple.Item1....N
Is this possible or not?
UPD: I want to create object with named parameters without new named type.
Upvotes: 47
Views: 70893
Reputation: 25965
Starting C# v7.0, it is now possible to give custom name to tuple properties. Earlier they used to have default names like Item1, Item2 and so on. Let's look at few variations which is now possible:
Naming the properties of Tuple Literals:
var personDetails = (Name: "Foo", Age: 22, FavoriteFood: "Bar");
Console.WriteLine($"Name - {personDetails.Name}, Age - {personDetails.Age}, Favorite Food - {personDetails.FavoriteFood}");
The output on console:
Name - Foo, Age - 22, Favorite Food - Bar
Returning Tuple (having named properties) from a method:
static void Main(string[] args)
{
var empInfo = GetEmpInfo();
Console.WriteLine($"Employee Details: {empInfo.firstName}, {empInfo.lastName}, {empInfo.computerName}, {empInfo.Salary}");
}
static (string firstName, string lastName, string computerName, int Salary) GetEmpInfo()
{
//This is hardcoded just for the demonstration. Ideally this data might be coming from some DB or web service call
return ("Foo", "Bar", "Foo-PC", 1000);
}
The output on console:
Employee Details: Foo, Bar, Foo-PC, 1000
Creating a list of Tuples having named properties:
var tupleList = new List<(int Index, string Name)>
{
(1, "cow"),
(5, "chickens"),
(1, "airplane")
};
foreach (var tuple in tupleList)
Console.WriteLine($"{tuple.Index} - {tuple.Name}");
Output on console:
1 - cow
5 - chickens
1 - airplane
Note: Code snippets in this post are using string interpolation feature of C# which was introduced in version 6 as detailed here.
Upvotes: 43
Reputation: 314
Now you can do it with tuple Name in C#
For Lambda Expression:
private static (string Name, string Age) methodTuple() => ( "Nick", "Twenty" );
Or
private static (string Name, string Age) methodTuple()
{
return ( "Nick", "Twenty" );
}
Do not use class type for Tuple
. Use primitive type to set the name in Tuple
.
Upvotes: 5
Reputation: 125660
You need to declare a helper class to do so.
public class MyResult
{
public string Name { get; set; }
public string Age { get; set; }
}
What you're trying to return is an anonymous type. As the name suggests you don't know what its name is, so you can't declare your method to return it.
Anonymous Types (C# Programming Guide)
You cannot declare a field, a property, an event, or the return type of a method as having an anonymous type. Similarly, you cannot declare a formal parameter of a method, property, constructor, or indexer as having an anonymous type. To pass an anonymous type, or a collection that contains anonymous types, as an argument to a method, you can declare the parameter as type object. However, doing this defeats the purpose of strong typing. If you must store query results or pass them outside the method boundary, consider using an ordinary named struct or class instead of an anonymous type.
Update
C#7 introduces Tuple support built into the language and it comes with named tuples
(string name, int age) methodTuple()
{
(...)
}
Read more on learn.microsoft.com: https://learn.microsoft.com/en-us/dotnet/articles/csharp/csharp-7#tuples
Upvotes: 23
Reputation: 1
As per me, when you want to return or get many things from a single method, better make its return type as CLASS but if you intend to use Tuple which itself is Class then for better naming this new class should inherit from Tuple. e.g. mentioned below.
public CustomReturn ExecuteTask( int a, string b, bool c, object d )
{
// Calling constructor of CustomReturn Class to set and get values
return new CustomReturn(a,b,c,d);
}
internal class CustomReturn
// for tuple inherit from Tuple<int,string,bool,object,double>
{
//for tuple public int A{ get {this.Item1} private set;}
public int A{get;private set;}
public string B{get;private set;}
public bool C{get;private set;}
public object D{get;private set;}
public CustomReturn (int a, string b, bool c, object d )
// use this line for tuple ": base( obj, boolean )"
{
this.A = a;
this.B = b;
this.C = c;
this.D = d;
}
}
Main(args)
{
var result = ExecuteTask( 10, "s", true, "object" );
// now if u have inherited Tuple for CustomReturn class then
// on doing result. you will get your custom name as A,B,C,D for //Item1,Item2,Item3,Item4 respectively also these Item1,Item2,Item3,Item4 will also be there.
}
Upvotes: 0
Reputation: 6056
In C# 7.0 (Visual Studio 2017) there is a new option to do that:
(string first, string middle, string last) LookupName(long id)
Upvotes: 54
Reputation: 14734
I usually create a new type that derives from Tuple, and map your explicit properties to return the base class's ItemX properties. eg:
public class Person : Tuple<string, string>
{
public Key(string name, string age) : base(name, age) { }
public string Name => Item1;
public string Age => Item2;
}
Upvotes: 1
Reputation: 1171
Unfortunately, this is not possible using the "Tuple" type, as it is defined as "Item1...N" in MSDN. So this exception is valid.
This method can compile in 3 ways: 1.) Change return type to object - this will create an "anonymous" type, which you can then use later. It is not particularly useful if you want to access the "Name" or "Age" property later without some additional work. 2.) Change return type to dynamic - this will let you access the "Name" and "Age" property, but will make the entire program (just the DLL where this method is located really) slightly slower as the use of dynamic necessitates throwing out some strong typing. 3.) Create a class and use it as teh return type.
Sample code here:
private static object ObjectTuple()
{
return new { Name = "Nick", Age = "Twenty" };
}
private static dynamic DynamicTuple()
{
return new { Name = "Nick", Age = "Twenty" };
}
private static Temp TempTuple()
{
return new Temp{ Name = "Nick", Age = "Twenty" };
}
class Temp
{
public string Name { get; set; }
public string Age { get; set; }
}
Upvotes: 0
Reputation: 203839
This is not possible with Tuple
, no. You'll need to create your own new named type to do this.
Upvotes: 6