4

I am asking about a recommendation to use getters and setters. I wrote the same code in two versions: using getters and setters and using just the class method. And I can't clearly see the difference between them.

I wrote the class Book with the private field rating. And the constructor Book can assign something to Book.rating by RatingSetter or by RatingMethod. RatingMethod only sets the values, but I can also create a method only for getting values.

class Book
    {
        public string title;
        public string author;
        private string rating;

        public Book(string title, string author, string rating)
        {
            this.title = title;
            this.author = author;
            RatingSetter = rating;
            RatingMethod(rating);
        }

        public string RatingSetter
        {
            get { return this.rating; }
            set
            {
                if (value == "PG" || value == "PG-13" || value == "R")
                {
                    rating = value;
                }
                else
                {
                    rating = "NR";
                }
            }
        }

        public string RatingMethod(string rating)
        {
            if (rating == "PG" || rating == "PG-13" || rating == "R")
            {
                return this.rating = rating;
            }
            else
            {
                return this.rating = "NR";
            }
        }
    }

In my opinion, there is no difference about security, validation or anything. Could anyone guide and help me to understand what's the difference and why is it recommended to use getters and setters.

minus.273
  • 755
  • 11
  • 24
morhhn
  • 71
  • 1
  • 4
  • 2
    They internally do the same thing. The difference is in the semantics of how you use them. – David Feb 03 '19 at 13:23
  • I disagree with comment and answer. [Why properties matter](http://csharpindepth.com/Articles/Chapter8/PropertiesMatter.aspx) – Crowcoder Feb 03 '19 at 13:42
  • @Crowcoder: One of the first sentences in the article you link states: `"It's worth being clear that this article does not address the question of whether something should be a method or a property."` Which is exactly what's being asked in the question above. So if the article you're referencing explicitly does not address this question, what exactly are you suggesting? – David Feb 03 '19 at 14:56
  • @David that's not how I interpreted the question but I get your point. I took it more generally, not so much "should *this* specific thing be a property or should it be a method?" – Crowcoder Feb 03 '19 at 15:01
  • @David it's interesting that this was marked as a duplicate of a more general question of best practices that Jon Skeet answered. Are you voting to reopen? – Crowcoder Feb 03 '19 at 15:32

3 Answers3

7

Getters and setters are just syntactic sugar. The compiler will compile your getters and setters into getter and setter methods eventually. So by writing getter and setter methods yourself, you are kind of doing the job of the compiler.

Therefore, I recommend you to use getters and setters, because one of their main purposes is to replace getter and setter methods.

Here are some other advantages of using getters and setters:

  • Getters and setters can save you a lot of time if you only need getters and setters without any logic:

    public int Property { get; set; }
    
  • In my opinion, the aesthetic of getters and setters look better. Compare:

    obj1.Property += obj2.Property;
    

    with

    obj1.SetProperty(obj1.GetProperty() + obj2.GetProperty());
    

    I feel like the latter just has too many parentheses.

  • Keep the setters and getters close to the property declaration. If you use getter and setter methods, you could accidentally write other methods between the property declaration and the getter/setter methods, causing the getter/setter methods to slowly "drift away" from the property declaration. Next time you want to find it, you need to scroll up and down. With getters and setters, they will always be below the property declaration.

Aryan Beezadhur
  • 4,503
  • 4
  • 21
  • 42
Sweeper
  • 213,210
  • 22
  • 193
  • 313
  • I was about understand, but then I start to reread your post many times and now I am totally lost. I know that this properties are just syntactic sugar, but I can't see why. - If I only need property without any logic. Compare: `public int Property { get; set; }` and `public int property;` - If I need some logic like a validation I wrote the comparation code in the top post. – morhhn Feb 03 '19 at 17:14
  • @morhhn `public int property;` is a filed, not a property. And public fields are very much discouraged. – Sweeper Feb 03 '19 at 17:18
  • @morhhn [This](https://stackoverflow.com/q/295104/5133585) and [this](https://stackoverflow.com/q/1180860/5133585) might help. – Sweeper Feb 03 '19 at 17:24
1

From Microsoft,

A property is a member that provides a flexible mechanism to read, write, or compute the value of a private field.

Which is basically their way of saying that a property is a purpose built member, that exists solely for wrapping and accessing private members, enabling the "data to be accessed easily and still helps promote the safety and flexibility of methods."

In your example, I would rename RatingSetter simply to Rating and treat it as though you would a normal public field. This promotes ease of use and lessens confusion when other people use your code. It is more obvious what you are doing and what needs to be done.

It is also not advisable to have public fields, e.g public string title; Instead it is usually better to opt for using a property to wrap this field and make it private e.g.

private string title;
public string Title {get; set;}

You can then use the public property outside of your class, but now have more control over what happens when someone accesses or sets the variable.

private string title;
public string Title {get; private set;}

Which will only allow read access from outside of the class.

Logging is now easier, since you can implement it in the setter:

private string title;
public string Title 
{
    get{ return title;}
    set
    {
        // Logging Code Here
        title = value;
    }
}

So to summarise, properties are concise and the functionality obvious, like a field, but with all the power and flexibility of a method.

Daniel Mackenzie
  • 204
  • 3
  • 14
  • Why more flexible? Why more coherent? – Enigmativity Feb 03 '19 at 13:57
  • More flexible than a standard public field as you have the option to add more functionality in the property body. More coherent as it is more obviously emulating accesses and writing to the property. – Daniel Mackenzie Feb 03 '19 at 14:16
  • @Enigmativity Because you ca log the accesses to getters/setters. You can transform values before you get/set them. For example `Minute {get}` and `Hour {get}` and store only one value from which it will be computed. You can provide access to properties of another fields `int ProductId => _product.Id`. You can allow only setting or only getting the property. Or different access modifier for each. With field, you cant do these things. – Ondřej Kubíček Feb 03 '19 at 14:17
  • @OndřejKubíček - The question isn't about fields. – Enigmativity Feb 03 '19 at 14:20
  • @Enigmativity And about what? – Ondřej Kubíček Feb 03 '19 at 14:21
  • @DanielMackenzie - The question isn't about fields. And what does "more obviously emulating accesses and writing to the property" mean? – Enigmativity Feb 03 '19 at 14:21
  • @OndřejKubíček - the difference between properties and methods. – Enigmativity Feb 03 '19 at 14:22
  • @Enigmativity For example you cannot write getter for int, but setter for double with the same name. The setter and getter methods can be named many different ways and confuse the user. (`GetId()`, `getid()` od `Id()`) And with properties the call looks a lot better without so many parentheses. – Ondřej Kubíček Feb 03 '19 at 14:31
  • @Enigmativity Apologies, after rereading what I wrote in a hurry, I meant something more along the lines of "emulating the field". By that, I mean it's the best of both worlds, a middle ground between a method and a plain field. It's concise and the functionality obvious, like a field. but with all the power and flexibility of a backing method. – Daniel Mackenzie Feb 03 '19 at 15:31
  • 1
    @DanielMackenzie - You should have had the statement "It's concise and the functionality obvious, like a field, but with all the power and flexibility of a method" (slightly edited) in your answer. – Enigmativity Feb 03 '19 at 21:45
0

The functionality is the same. But it makes the code more readable and understandable.

In your example you validate rating by calling RatingSetter or RatingMethod. Consider you work in a team and your co-worker doesn't know about the validation methods and simply calls this.rating = someValue. With your example there wouldn't be any validation. My code example (untested) ensures that the validation is done on every value assign.

private string rating {
     get { return this.rating; }
        set
        {
            if (value == "PG" || value == "PG-13" || value == "R")
            {
                rating = value;
            }
            else
            {
                throw new UnknownRatingException();

            }
        }
}

public Book(string title, string author, string rating)
    {
        this.title = title;
        this.author = author;
        this.rating = rating //the set property is called
    }
Alina J
  • 155
  • 1
  • 10
  • Why is it more readable and understandable? Can you show both ways to explain? – Enigmativity Feb 03 '19 at 13:42
  • 1
    I'd use `throw new UnknownRatingException()` in the `else` clause instead to show a nice particular use case – the default. Feb 03 '19 at 13:42
  • Your answer is getting worse. Your final paragraph doesn't address the question and just confuses the matter. The question is about why one way is preferable over the other. It's not about the necessity of methods. It's also not about safety. – Enigmativity Feb 03 '19 at 13:56
  • My example shows how you can reduce your code by using setters and getters. Because of this you can get rid of some extra methods. And I didn't wrote that its absolutely safe, I wrote it is safer. – Alina J Feb 03 '19 at 14:05
  • @AlinaJ - No, it doesn't. You need to show both ways of writing the code and then discuss the differences. Also, there is no validation benefit to properties over methods. – Enigmativity Feb 03 '19 at 14:18