Is Using .NET 4.0 Tuples in my C# Code a Poor Desi

2019-01-10 01:21发布

With the addition of the Tuple class in .net 4, I have been trying to decide if using them in my design is a bad choice or not. The way I see it, a Tuple can be a shortcut to writing a result class (I am sure there are other uses too).

So this:

public class ResultType
{
    public string StringValue { get; set; }
    public int IntValue { get; set; }
}

public ResultType GetAClassedValue()
{
    //..Do Some Stuff
    ResultType result = new ResultType { StringValue = "A String", IntValue = 2 };
    return result;
}

Is equivalent to this:

public Tuple<string, int> GetATupledValue()
{
    //...Do Some stuff
    Tuple<string, int> result = new Tuple<string, int>("A String", 2);
    return result;
}

So setting aside the possibility that I am missing the point of Tuples, is the example with a Tuple a bad design choice? To me it seems like less clutter, but not as self documenting and clean. Meaning that with the type ResultType, it is very clear later on what each part of the class means but you have extra code to maintain. With the Tuple<string, int> you will need to look up and figure out what each Item represents, but you write and maintain less code.

Any experience you have had with this choice would be greatly appreciated.

13条回答
神经病院院长
2楼-- · 2019-01-10 01:32

Tuples are great if you control both creating and using them - you can maintain context, which is essential to understanding them.

On a public API, however, they are less effective. The consumer (not you) has to either guess or look up documentation, especially for things like Tuple<int, int>.

I would use them for private/internal members, but use result classes for public/protected members.

This answer also has some info.

查看更多
在下西门庆
3楼-- · 2019-01-10 01:33

It depends, of course! As you said, a tuple can save you code and time when you want to group some items together for local consumption. You can also use them to create more generic processing algorithms than you can if you pass a concrete class around. I can't remember how many times I've wished I had something beyond KeyValuePair or a DataRow to quickly pass some date from one method to another.

On the other hand, it is quite possible to overdo it and pass around tuples where you can only guess what they contain. If you are going to use a tuple across classes, perhaps it would be better to create one concrete class.

Used in moderation of course, tuples can lead to more concise and readable code. You can look to C++, STL and Boost for examples of how Tuples are used in other languages but in the end, we will all have to experiment to find how they best fit in the .NET environment.

查看更多
对你真心纯属浪费
4楼-- · 2019-01-10 01:33

I've used tuples, both the Tuple and the new ValueTuple, in a number of different scenarios and arrived at the following conclusion: do not use.

Every time, I encountered the following issues:

  • code became unreadable due to lack of strong naming;
  • unable to use class hierarchy features, such as base class DTO and child class DTOs, etc.;
  • if they are used in more than one place, you end up copying and pasting these ugly definitions, instead of a clean class name.

My opinion is tuples are a detriment, not a feature, of C#.

I have somewhat similar, but a lot less harsh, criticism of Func<> and Action<>. Those are useful in many situations, especially the simple Action and Func<type> variants, but anything beyond that, I've found that creating a delegate type is more elegant, readable, maintainable, and gives you more features, like ref/out parameters.

查看更多
forever°为你锁心
5楼-- · 2019-01-10 01:34

Similar to keyword var, it is intended as a convenience - but is as easily abused.

In my most humble opinion, do not expose Tuple as a return class. Use it privately, if a service or component's data structure requires it, but return well-formed well-known classes from public methods.

// one possible use of tuple within a private context. would never
// return an opaque non-descript instance as a result, but useful
// when scope is known [ie private] and implementation intimacy is
// expected
public class WorkflowHost
{
    // a map of uri's to a workflow service definition 
    // and workflow service instance. By convention, first
    // element of tuple is definition, second element is
    // instance
    private Dictionary<Uri, Tuple<WorkflowService, WorkflowServiceHost>> _map = 
        new Dictionary<Uri, Tuple<WorkflowService, WorkflowServiceHost>> ();
}
查看更多
太酷不给撩
6楼-- · 2019-01-10 01:37

Tuples can be useful... but they can also be a pain later. If you have a method that returns Tuple<int,string,string,int> how do you know what those values are later. Were they ID, FirstName, LastName, Age or were they UnitNumber, Street, City, ZipCode.

查看更多
Fickle 薄情
7楼-- · 2019-01-10 01:38

Tuples are a useless framework feature in .NET 4. I think a great opportunity was missed with C# 4.0. I would have loved to have tuples with named members, so you could access the various fields of a tuple by name instead of Value1, Value2, etc...

It would have required a language (syntax) change, but it would have been very useful.

查看更多
登录 后发表回答