dennisdoomen / CSharpGuidelines

A set of coding guidelines for C# 9.0, design principles and layout rules for improving the overall quality of your code development.
https://www.csharpcodingguidelines.com
Other
746 stars 271 forks source link

Revisit: parameters and tuples #140

Closed bkoelman closed 6 years ago

bkoelman commented 6 years ago

It looks like https://github.com/dennisdoomen/CSharpGuidelines/pull/127 was merged, but then lost in the site migration process. So the change did not make it into the current release.

That's fortunate, because I would like to revisit my earlier proposal at https://github.com/dennisdoomen/CSharpGuidelines/pull/127, which limited the number of values flowing in and out to four.

An alternative approach would be to keep the number of incoming values to 3, and then allow at most 2 (or 3) values going out.

The earlier proposal allowed incoming tuples, which may not be so practical after all. Consider the next code snippet:

class Demo
{
    (string First, string Middle, string Last) GetName() => throw new NotImplementedException();

    void SaveName((string First, string Middle, string Last) name) => throw new NotImplementedException();
    void SaveName(string first, string middle, string last) => throw new NotImplementedException();

    void Caller()
    {
        var name = GetName();

        SaveName(name);
        SaveName(name.First, name.Middle, name.Last);
    }
}

Only in the example above the tuple-based overload makes the calling code a bit shorter. But it seems like a theoretical example. What are the benefits of tuple parameters, if any?

Also the existing rule is a bit ambiguous: the first overload of SaveName has 3 or 4 incoming values, depending on whether name is included in the count.

Maybe it would be better to advice against tuple parameters?

dennisdoomen commented 6 years ago

Yeah, I kind of agree. I don't see the value of passing in a tuple like that either. However, you might want to pass in a collection of tuples. Not sure if that's even possible though.

bkoelman commented 6 years ago

It is possible. This is valid code:

List<(string, int)> list = new List<(string, int)> { ("a", 1), ("b", 2) };
(string, int)[] array = { ("a", 1), ("b", 2) };
dennisdoomen commented 6 years ago

Maybe that should be the exception.

bkoelman commented 6 years ago

Ok. So, to summarize:

  1. Max 3 parameters, no tuples (exception: collection of tuples)
  2. Max 2 (or 3?) return values

Some additional guidance I found elsewhere:

dennisdoomen commented 6 years ago

I think returning two values should be enough. More than that feels like its going to cause the problem the last bullet tries to avoid.