RichK
RichK

Reputation: 11879

Why define the getter before the setter (coding convention)

I appreciate this question is a little silly, so I apologise in advance if this is off topic or non constructive.

Why, in C# is it standard convention* to define properties with the getter before the setter? For properties with both you're almost always going to use the setter before the getter so it's in a valid state. Therefore, it seems a little backward to me that we define the getter first.

Also, the setter would typically have some validation logic, which the getter doesn't need. Would it not be tidier to have this logic ahead of the getter to make it clearer how the property should behave. For example:

public decimal Price
{
    get { return _price; }
    set
    {
        if(value < 0m)
        {
            throw new ArgumentOutOfRangeException();
        }

        _price = value;
        OnPropertyChanged("Price");
    }
}

The code in the setter is far more interesting than the getter, should it not take precedence and be defined first?

*I know there are no rules with these things, but practically every example ever, ever of properties defines the getter before the setter.

Upvotes: 2

Views: 2731

Answers (5)

Serious Angel
Serious Angel

Reputation: 1564

I agree with such a both interesting and adequate point of view of @YoryeNathan.

I had been curious about the importance of the order, too, with the most frequently conclusion raised: Shouldn't be the data representation important in the code, and its flow in general? So we can get anything once and only when we set it previously. Sure thing, set is the first!", but... I do still see the following in my code:

return [
    'a' => 1,
    'b' => 2,

    'c' => [
        'a' => 1,
        'd' => 3,
    ],
];

...and when I looked closer, I see that the first are the more simple or shorter data to also allow more of it appear on the screen, yet still be in an organized structure. Whether it be a configuration or data file like JSON/YAML or a source code member like a class, it feels that items like '{ enabled: true; }' should be higher and with more complex data moved down.

Considering that, "commonly" (based on subjective experience), getters are shorter, indeed, than setters in general classes or complex relatively non-standard DTOs even with additional validation and "seal" features, having getters at higher, and having those in member-scope groups, makes it more adequate I do believe. Not to mention that "get/set" should be in groups.

Example

<?php

use InvalidArgumentException;

class C1C2
{
    // Public Fields
    // ----------------------------------------------------------------

    public readonly ?int $a;

    // Protected Fields
    // ----------------------------------------------------------------

    protected readonly ?int $b;

    // Private Fields
    // ----------------------------------------------------------------

    private ?int $c1;

    private ?int $c2;

    // Constructor
    // ----------------------------------------------------------------

    public function __construct(int $a, int $b)
    {
        $this->a = $a;
        $this->b = $b;
    }

    // Getters/Setters
    // ----------------------------------------------------------------
    // C1
    // --------------------------------

    public function getC1(): int
    {
        return $this->c1;
    }

    public function setC1(int $value): void
    {
        if ($value <= 0) {
            throw new InvalidArgumentException();
        }

        $this->c1 = $value;
    }

    // C2
    // --------------------------------

    public function getC2(): int
    {
        return $this->c2;
    }

    public function setC2(int $value): void
    {
        if ($value <= 0 || $value > 200) {
            throw new InvalidArgumentException();
        }

        $this->c2 = $value;
    }
}

?>

Related

Which order to define getters and setters in?

Upvotes: -2

Adam Houldsworth
Adam Houldsworth

Reputation: 64517

Because it is better to give than to receive.

On a more serious note, I'm guessing because whoever wrote the snippet (or whatever it is that auto-gens the property code in VS) subconsciously chose this order.

Then as the rest of us are just sheep to this pioneering shepherd, we followed without question.

Until you.

You question our once great shepherd, anarchy can only ensue. Commit your code and run for the hills.

Upvotes: 19

Iridium
Iridium

Reputation: 23731

I think the important thing here is consistency. Whilst in your example, the setter is "more interesting", I don't think that this is necessarily the case the majority of the time. Indeed, one of the reasons that auto-properties are so useful is because of the frequency with which the get and set code simply read from/write to a private field with no other processing, in which case neither is "more interesting".

In your own projects, you are of course free to put them in any order that you like, and if you decide that setters should come first based on "importance" or some other reason, you're entirely free to do so. However given the widespread nature of the getter-before-setter convention, if you plan on sharing your code, it would make sense to follow convention for the sake of those that may need to read or change it in future.

Upvotes: 0

Hari
Hari

Reputation: 4622

The order of the getter and setter are totally irrevelant, I think the reason for the convention is Visual Studio's property snippet which generated the properties in this way (getter before setter). So after using this snippet a couple of times this order have become an unwritten, unconsious practice for most coders (including myself). This of course doesn't explain why did VS designers implement the snippet this way. My opinion: they don't know it, and they don't care about it, or maybe because g comes earlier in the english alphabet than s. Anyway who on the world has so much time to care?

Upvotes: 1

YoryeNathan
YoryeNathan

Reputation: 14522

The getter is usually a lot shorter (usually one-line), so putting it in the beginning allows you to overview better, just like you will prefer this:

if (condition)
{
    // Short code
}
else
{
    // Long code
    // Long code
    // Long code
    // Long code
    // Long code
    // Long code
    // Long code
    // Long code
    // Long code
    // Long code
    // Long code
    // Long code
    // Long code
    // Long code
    // Long code
    // Long code
    // Long code
}

instead of this:

if (!condition)
{
    // Long code
    // Long code
    // Long code
    // Long code
    // Long code
    // Long code
    // Long code
    // Long code
    // Long code
    // Long code
    // Long code
    // Long code
    // Long code
    // Long code
    // Long code
    // Long code
    // Long code
}
else
{
    // Short code
}

And more than that - just because.

Upvotes: 12

Related Questions