I love Tuples
-
IMHO, in recent years, the best feature MS has added to the C# is Tuple. It helps make code cleaner and quicker to write. It can be compared to Generic lists.
Behzad
-
IMHO, in recent years, the best feature MS has added to the C# is Tuple. It helps make code cleaner and quicker to write. It can be compared to Generic lists.
Behzad
Behzad Sedighzadeh wrote:
It helps make code cleaner and quicker to write
Quicker to write, Okay! Cleaner? I don't think so. Create a nested tuple and now you don't know which element you are referring to when you say Item2. It makes code difficult to maintain. So for simple return types that has like 2 or 3 primitive data types tuple is fine, otherwise just create a class.
-
IMHO, in recent years, the best feature MS has added to the C# is Tuple. It helps make code cleaner and quicker to write. It can be compared to Generic lists.
Behzad
Yes, tuples are great, especially as a replacement for
out string foo
and I use them primarily for returning multiple things for rather low level methods whenout
or a C# class/struct is just overkill. The fact that the tuple parameters can be named was a huge advancement, rather than having to useItem1
,Item2
, etc. That said, I use them judiciously and always ask myself, if I'm using a tuple here, is that the right approach or am I compensating for a possibly bad "design." For example (this from code I have in a library):public (HttpStatusCode status, string content) Get(string url, Dictionary headers = null) { var client = RestClientFactory(); var request = new RestRequest(url, Method.Get); headers?.ForEach(kvp => request.AddHeader(kvp.Key, kvp.Value)); RestResponse response = client.Execute(request); return (response.StatusCode, response.Content); }
Why am I parsing out the status code and content instead of just returning the
response
object? One answer is that returningresponse
may probably require ausing RestSharp
and even a reference to the RestSharp package in the caller project. OK, maybe that's a defensible argument, maybe not. After using this library of mine (REST is just one small part of this library) I'm not that thrilled with my initial wrapper implementation. But because I started this "pattern", it continues, like:public (T item, HttpStatusCode status, string content) Get(string url, Dictionary headers = null) where T : new() { var client = RestClientFactory(); var request = new RestRequest(url, Method.Get); headers?.ForEach(kvp => request.AddHeader(kvp.Key, kvp.Value)); RestResponse response = client.Execute(request); T ret = TryDeserialize(response); return (ret, response.StatusCode, response.Content); }
And this illustrates mashing together various potentially bad implementation/designs. The tuple now returns three things, and the
TryDeserialize
catches exceptions silently, returning a null forT item
, and what if I want the actual deserialization exception? And now that I look at that code again after a couple years, what's with thatAddHeader
loop when there's a perfectly -
Behzad Sedighzadeh wrote:
It helps make code cleaner and quicker to write
Quicker to write, Okay! Cleaner? I don't think so. Create a nested tuple and now you don't know which element you are referring to when you say Item2. It makes code difficult to maintain. So for simple return types that has like 2 or 3 primitive data types tuple is fine, otherwise just create a class.
GKP1992 wrote:
Create a nested tuple and now you don't know which element you are referring to when you say Item2
Tuple "items" can be named, so:
var name = GetMyName();
where:(string firstName, string lastName) GetMyName()
{
return ("Marc", "Clifton");
}I can use
name.firstName
andname.lastName
Most of the time. ;)Latest Articles:
A Lightweight Thread Safe In-Memory Keyed Generic Cache Collection Service A Dynamic Where Implementation for Entity Framework -
GKP1992 wrote:
Create a nested tuple and now you don't know which element you are referring to when you say Item2
Tuple "items" can be named, so:
var name = GetMyName();
where:(string firstName, string lastName) GetMyName()
{
return ("Marc", "Clifton");
}I can use
name.firstName
andname.lastName
Most of the time. ;)Latest Articles:
A Lightweight Thread Safe In-Memory Keyed Generic Cache Collection Service A Dynamic Where Implementation for Entity FrameworkBut is that C#?
-
But is that C#?
Yes
Check out my IoT graphics library here: https://honeythecodewitch.com/gfx And my IoT UI/User Experience library here: https://honeythecodewitch.com/uix
-
IMHO, in recent years, the best feature MS has added to the C# is Tuple. It helps make code cleaner and quicker to write. It can be compared to Generic lists.
Behzad
I don't use them much. I usually prefer to create a class. It kinda depends on how important the thing is.
-
Yes, tuples are great, especially as a replacement for
out string foo
and I use them primarily for returning multiple things for rather low level methods whenout
or a C# class/struct is just overkill. The fact that the tuple parameters can be named was a huge advancement, rather than having to useItem1
,Item2
, etc. That said, I use them judiciously and always ask myself, if I'm using a tuple here, is that the right approach or am I compensating for a possibly bad "design." For example (this from code I have in a library):public (HttpStatusCode status, string content) Get(string url, Dictionary headers = null) { var client = RestClientFactory(); var request = new RestRequest(url, Method.Get); headers?.ForEach(kvp => request.AddHeader(kvp.Key, kvp.Value)); RestResponse response = client.Execute(request); return (response.StatusCode, response.Content); }
Why am I parsing out the status code and content instead of just returning the
response
object? One answer is that returningresponse
may probably require ausing RestSharp
and even a reference to the RestSharp package in the caller project. OK, maybe that's a defensible argument, maybe not. After using this library of mine (REST is just one small part of this library) I'm not that thrilled with my initial wrapper implementation. But because I started this "pattern", it continues, like:public (T item, HttpStatusCode status, string content) Get(string url, Dictionary headers = null) where T : new() { var client = RestClientFactory(); var request = new RestRequest(url, Method.Get); headers?.ForEach(kvp => request.AddHeader(kvp.Key, kvp.Value)); RestResponse response = client.Execute(request); T ret = TryDeserialize(response); return (ret, response.StatusCode, response.Content); }
And this illustrates mashing together various potentially bad implementation/designs. The tuple now returns three things, and the
TryDeserialize
catches exceptions silently, returning a null forT item
, and what if I want the actual deserialization exception? And now that I look at that code again after a couple years, what's with thatAddHeader
loop when there's a perfectly:-D I think there are very few people smarter than you.
The difficult we do right away... ...the impossible takes slightly longer.
-
IMHO, in recent years, the best feature MS has added to the C# is Tuple. It helps make code cleaner and quicker to write. It can be compared to Generic lists.
Behzad
I love them because sometimes it is convenient to return more than one value from a method, and the use case doesn't justify the overhead of creating and populating a POCO.
There are no solutions, only trade-offs.
- Thomas SowellA day can really slip by when you're deliberately avoiding what you're supposed to do.
- Calvin (Bill Watterson, Calvin & Hobbes) -
IMHO, in recent years, the best feature MS has added to the C# is Tuple. It helps make code cleaner and quicker to write. It can be compared to Generic lists.
Behzad
Tuples and anonymous classes have drastically reduced the number of single-use classes in my code :D
Best, Sander Azure DevOps Succinctly (free eBook) Azure Serverless Succinctly (free eBook) Migrating Apps to the Cloud with Azure arrgh.js - Bringing LINQ to JavaScript
-
GKP1992 wrote:
Create a nested tuple and now you don't know which element you are referring to when you say Item2
Tuple "items" can be named, so:
var name = GetMyName();
where:(string firstName, string lastName) GetMyName()
{
return ("Marc", "Clifton");
}I can use
name.firstName
andname.lastName
Most of the time. ;)Latest Articles:
A Lightweight Thread Safe In-Memory Keyed Generic Cache Collection Service A Dynamic Where Implementation for Entity FrameworkThe slightly weird thing that disturbs me about that is that firstName and lastName behave/look a lot like members of a class/struct yet don't have Pascal Case naming.
name.firstName
vs.name.FirstName
It reminds me of Javascript, and well you know what that can inflict on the soul.Regards, Rob Philpott.
-
GKP1992 wrote:
Create a nested tuple and now you don't know which element you are referring to when you say Item2
Tuple "items" can be named, so:
var name = GetMyName();
where:(string firstName, string lastName) GetMyName()
{
return ("Marc", "Clifton");
}I can use
name.firstName
andname.lastName
Most of the time. ;)Latest Articles:
A Lightweight Thread Safe In-Memory Keyed Generic Cache Collection Service A Dynamic Where Implementation for Entity Framework -
IMHO, in recent years, the best feature MS has added to the C# is Tuple. It helps make code cleaner and quicker to write. It can be compared to Generic lists.
Behzad
I don't use C# much these days but totally agree. And, digging the positivity man. :cool:
Jeremy Falcon
-
IMHO, in recent years, the best feature MS has added to the C# is Tuple. It helps make code cleaner and quicker to write. It can be compared to Generic lists.
Behzad
Like (almost) everything in C#, they have their uses. Loving them? No!
Freedom is the freedom to say that two plus two make four. If that is granted, all else follows. -- 6079 Smith W.
-
Tuples and anonymous classes have drastically reduced the number of single-use classes in my code :D
Best, Sander Azure DevOps Succinctly (free eBook) Azure Serverless Succinctly (free eBook) Migrating Apps to the Cloud with Azure arrgh.js - Bringing LINQ to JavaScript
100% agreed!
Behzad