1

Please help settle this argument. I have a public class with some properties. The set of the properties is private and get is public. The only way to set a property is to call the constructor. What are the benefits or drawbacks of this design? Is there any implications I should know of? My argument is if there's no benefit to private set why do it? The counter argument is there's not need to change the property after class is instantiated if the need arises modify the class to allow it.

Is this just philosophical or is there actual technical reasoning behind this?

public string Id
{
    get;
    private set;
}

UPDATE: Just to clarify the question. I'm not asking what private set is for and where to use it. I'm asking if you don't know if your properties will need to be changed outside of the constructor or not do you get a benefit from restricting the set. So I guess the question is if you don't know which way you're going is the answer keep it as restrictive as possible?

Tigran
  • 872
  • 1
  • 9
  • 25
  • what if you want to have the possibility to change the property from inside the class? – Liel Jan 16 '14 at 19:17
  • The main reason is just to hide setter from other classes. So no one can affect logic of your class by this variable – Sergey Litvinov Jan 16 '14 at 19:17
  • See also: http://programmers.stackexchange.com/questions/72495/net-properties-use-private-set-or-readonly-property – tnw Jan 16 '14 at 19:19
  • It's not clear what alternative you're suggesting - you've shown one piece of code, and asked whether it's better or worse than something else, but not said what the something is. – Jon Skeet Jan 16 '14 at 19:20
  • the private set is good for that parameters which will be the same all time of object life time. One of such case is Entity ID. Imagine what will be if somebody will change it. But there is a problem with Entity framewok which couldn't process private set and don't like parameters in constructor. So you may use internal set. It would be used as public is system area and as private in business logic layer – potehin143 Jan 16 '14 at 19:25
  • @JonSkeet the alternative is not to make set private. My expectation was that I will need to set the property from outside the class. But that's just an expectation at the time. – Tigran Jan 16 '14 at 22:30
  • @Tigran: So leave it public? Personally I prefer to keep types immutable where possible, but it's hard to give general advice without know more details. – Jon Skeet Jan 16 '14 at 22:54

3 Answers3

6

If there's no benefit to private set why do it?

That's the wrong way to look at it.

A public setter is a feature. It's got to be designed, documented, tested and maintained, or you've got to decide that you're OK with shipping an undesigned, undocumented, untested and unmaintained feature. My management wouldn't be OK with that but maybe yours is. You've got to decide what happens if someone sets it to null, what happens if someone sets it from another thread, and so on.

Since the public setter is the thing that has costs, the argument should be "if there's no benefit to a public setter then we must make it private, so as to avoid the costs of adding a feature with no benefit."

Public setters have more costs than just the obvious ones. A public setter means that you cannot make any logical inference about the value of the property in the present based on the value in the past. You have to assume that anyone could be changing that thing at any time. You are decreasing the number of known facts about your program and therefore increasing the likelihood that some part of your understanding of the program is wrong. Mutability makes programs harder to reason about.

The counter argument is there's no need to change the property after class is instantiated. If the need arises modify the class to allow it.

Right. If the feature buys you no benefit then don't pay its costs! If the need arises then make a business decision about whether the costs are worth it or not.

Eric Lippert
  • 647,829
  • 179
  • 1,238
  • 2,067
  • Good point. I think the whole thing hinges on if the properties need to change after Instantiation. My argument was that it's more likely I'll need to change the property in which case we would have to set it to public. – Tigran Jan 16 '14 at 22:02
  • I agree with your answer but just wanted to clarify. I'm looking in the future and I expect to change values from outside. This is why I was arguing. Of course it may turn out I'm not that good of a fortune teller. – Tigran Jan 16 '14 at 22:28
  • @Tigran: Then the question is: does the likely benefit of the feature exceed the *cost* of designing, implementing, testing, documenting and maintaining the feature? Moreover, while we are predicting the future: maybe in the future you want the property to be an integer or a string; should you make it an `object` today, in case you need that in the future? Maybe in the future you want an event raised when the property is changed; should you implement `INotifyPropertyChanged` today, in case you need that in the future? Maybe you want it to be overridable in the future; should it be virtual? – Eric Lippert Jan 16 '14 at 23:04
  • 1
    @Tigran: There are millions of things you *could* want in the future. How many of them are worth doing today? – Eric Lippert Jan 16 '14 at 23:05
  • good points all together. I've learned my lesson. – Tigran Jan 17 '14 at 18:00
4

The best answer is that it depends on your scenario. A class's public members are its contract with the outside world. As the designer of the class, you get to write the contract. Do you want to allow people to change the value of the property or not? If not, make it private. If so, make it public.

If it doesn't need to be public, make it private. Just like in the real world, keep the contract as simple as possible. Don't agree to anything you don't need to agree to.

TypeIA
  • 16,916
  • 1
  • 38
  • 52
  • simple and direct answer. Thanks. I just didn't see the need to make set private because I was expecting to change the values outside of the class. But changing values outside just an assumption at the time. So it's just a question of who can see into the future better. – Tigran Jan 16 '14 at 22:25
1

I do this whenever I need 'immutability' of a class - it cannot change during the lifetime of that class.

Also, it might not be an external thing that changes a property, it might even be computed every time.

Many good reasons for public get/private set.

n8wrl
  • 19,439
  • 4
  • 63
  • 103