106

I'm taking a C# class right now and I'm trying to find out the best way of doing things. I come from a Java background and so I'm only familiar with Java best-practices; I'm a C# novice!

In Java if I have a private property, I do this;

private String name;

public void setName(String name) {
   this.name = name;
}

public String getName() {
   return this.name;
}

In C#, I see that there are many ways of doing this.

I can do it like Java:

private string name;

public void setName(string name) {
   this.name = name;
}

public string getName() {
   return this.name;
}

Or I can do it this way:

private string name;

public string Name {
   get { return name; }
   set { name = value; }
}

Or:

public string Name { get; set; }

Which one should I use, and what are the caveats or subtleties involved with each approach? When creating classes, I am following general best-practices that I know from Java (especially reading Effective Java). So for example, I am favoring immutability (providing setters only when necessary). I'm just curious to see how these practices fit in with the various ways of providing setters and getters in C#; essentially, how would I translate best-practices from the Java world into C#?

EDIT

I was posting this as a comment to Jon Skeet's answer but then it got long:

What about a non-trivial property (i.e., with significant processing and validation perhaps)? Could I still expose it via a public property but with the logic encapsulated in get and set? Why would/should I do this over having dedicated setter and getter methods (with associated processing and validation logic).

Vivin Paliath
  • 94,126
  • 40
  • 223
  • 295

12 Answers12

98

Pre-C# 6

I'd use the last of these, for a trivial property. Note that I'd call this a public property as both the getters and setters are public.

Immutability is a bit of a pain with automatically implemented properties - you can't write an auto-property which only has a getter; the closest you can come is:

public string Foo { get; private set; }

which isn't really immutable... just immutable outside your class. So you may wish to use a real read-only property instead:

private readonly string foo;
public string Foo { get { return foo; } }

You definitely don't want to write getName() and setName(). In some cases it makes sense to write Get/Set methods rather than using properties, particularly if they could be expensive and you wish to emphasize that. However, you'd want to follow the .NET naming convention of PascalCase for methods, and you wouldn't want a trivial property like this to be implemented with normal methods anyway - a property is much more idiomatic here.

C# 6

Hooray, we finally have proper read-only automatically implemented properties:

// This can only be assigned to within the constructor
public string Foo { get; }

Likewise for read-only properties which do need to do some work, you can use member-bodied properties:

public double Area => height * width;
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 6
    More exact: any code reiew will point out the java way is a hack that is bypassing valid langauge AND (!) runtime constructs and kill the usage of the property as proeprty (i.e. object.property = "value"). In some teams this would result in a nice talk about attitude - depending on seniority combined with an incentive to put that attitude to use at a competitor. Seriously, DONT FIGHT THE LANGAUGE. Especially as the java "way" is a hack that was choosen in order not to modify the langauge for real property support. – TomTom Feb 09 '11 at 18:24
  • 1
    I guess the good news is my response doesn't seem to contradict anything you mentioned. The bad news is your fingers are far faster than mine. Great insight, and thanks for the added detail. – jeremyalan Feb 09 '11 at 18:37
  • 4
    To answer you edit: you can use the get/set methods with any amount of logic in them that you'd like. We often do this, especially for validation. Best practice, however, is not to have a lot of slow logic (database access for example), dangerous logic (exception throwing), or mutation (changing a lot of state) in the properties. A property is expected to act more or less like a simple state. Anything more should be indicated by using a function instead. – CodexArcanum Feb 09 '11 at 20:38
  • @JonSkeet I guess **you can write auto-properties with only a getter.** [Check Properties Overview here](http://msdn.microsoft.com/en-us/library/x9fsa0sw.aspx) – rtindru Jun 25 '13 at 09:24
  • @rtindru: No, you can't. You can write an automatically implemented property with a public getter and a private setter, but that's not the same thing. – Jon Skeet Jun 25 '13 at 09:59
  • @Jon Did you check the link? It had this line: _Properties that do not implement a set accessor are read only._ – rtindru Jun 25 '13 at 10:01
  • 2
    @rtindru: Yes, I'm aware of that. It's entirely possible to write a read-only property. But you can't declare an *automatically-implemented* property without a set accessor. – Jon Skeet Jun 25 '13 at 10:02
  • 2
    As of C# 6 [you can now have auto properties without a set accessor](https://github.com/dotnet/roslyn/wiki/Languages-features-in-C%23-6-and-VB-14), (`public int Y { get; } = y;`). – Scott Chamberlain Apr 25 '15 at 22:49
  • @JonSkeet Is the practice of having public getter and private setting changed if the property is a reference type .e.g Dictionary ? – cscmh99 Feb 03 '17 at 03:50
  • @cscmh99: Not really - you just need to be aware when you're exposing mutable state. You wouldn't necessarily make the setter public just because you're exposing a reference to a mutable object though. – Jon Skeet Feb 03 '17 at 06:58
18

If all you need is a variable to store some data:

public string Name { get; set; }

Want to make it appear read-only?

public string Name { get; private set; }

Or even better...

private readonly string _name;

...

public string Name { get { return _name; } }

Want to do some value checking before assigning the property?

public string Name 
{
   get { return m_name; }
   set
   {
      if (value == null)
         throw new ArgumentNullException("value");

      m_name = value;
   }
}

In general, the GetXyz() and SetXyz() are only used in certain cases, and you just have to use your gut on when it feels right. In general, I would say that I expect most get/set properties to not contain a lot of logic and have very few, if any, unexpected side effects. If reading a property value requires invoking a service or getting input from a user in order to build the object that I'm requesting, then I would wrap it into a method, and call it something like BuildXyz(), rather than GetXyz().

jeremyalan
  • 4,658
  • 2
  • 29
  • 38
  • 2
    I would not throw exceptions in properties, I'd rather use method setters with contracts to specify such specific behavior. If a property is of type int, I'd expect every int to qualify. Something which calls for exception throwing is not _simple_ in my opinion, INotifyPropertyChanged type invocations are more in that line according to me. – flindeberg Jan 19 '12 at 09:08
  • 3
    private setter != immutable – piedar May 15 '14 at 15:52
  • piedar is right. A private setter just means I can't make assignments, but I can still use `myList.Add()`, for example (as long as the object is exposed to change, it's mutable). –  Dec 30 '15 at 03:33
  • 1
    @flindeberg Sorry but I disagree... What about if you've got a progress bar with a `Min`/`Max` value. You want to ensure that `Max > Min`? Having a `SetRange(Min, Max)` might make sense but then how are you going to read those values back? Readonly Min/Max properties? Throwing exceptions for invalid input seems like the cleanest way to handle this. – Basic Oct 09 '16 at 19:14
13

Use properties in C#, not get/set methods. They are there for your convenience and it is idiomatic.

As for your two C# examples, one is simply syntactic sugar for the other. Use the auto property if all you need is a simple wrapper around an instance variable, use the full version when you need to add logic in the getter and/or setter.

Ed S.
  • 122,712
  • 22
  • 185
  • 265
5

In C# favor properties for exposing private fields for get and/or set. The thie form you mention is an autoproperty where the get and set automatically generate a hidden pivot backing field for you.

I favor auto properties when possible but you should never do a set/get method pair in C#.

James Michael Hare
  • 37,767
  • 9
  • 73
  • 83
5
public string Name { get; set; }

This is simply a auto-implemented property, and is technically the same as a normal property. A backing field will be created when compiling.

All properties are eventually converted to functions, so the actual compiled implementation in the end is the same as you are used to in Java.

Use auto-implemented properties when you don't have to do specific operations on the backing field. Use a ordinary property otherwise. Use get and set functions when the operation has side effects or is computationally expensive, use properties otherwise.

Steven Jeuris
  • 18,274
  • 9
  • 70
  • 161
4

Regardless of which way you choose in C# the end result is the same. You will get a backinng variable with separate getter and setter methods. By using properties you are following best practices and so it's a matter of how verbose you want to get.

Personally I would choose auto-properties, the last version: public string Name { get; set; }, since they take up the least amount of space. And you can always expand these in the future if you need add something like validation.

Paul Sasik
  • 79,492
  • 20
  • 149
  • 189
4

Whenever possible I prefer public string Name { get; set; } as it's terse and easily readable. However, there may be times when this one is necessary

private string name;

public string Name {
   get { return name; }
   set { name = value; }
}
SquidScareMe
  • 3,108
  • 2
  • 24
  • 37
  • 2
    can you explain when and why that kind of thing is necessary? – Jesper Feb 09 '11 at 20:17
  • Right now I cannot think of a reason to use the 2nd version. I only said 'may be times when this is necessary'. I hate to use absolutes unless I'm positive. – SquidScareMe Feb 10 '11 at 14:24
  • 3
    And why is this 'lolz'? You can show your support for a comment by upvoting. – SquidScareMe Feb 10 '11 at 14:24
  • 1
    One reason to use an explicit backing field is when you want to do atomic/thread-safe operations against the value – Basic Oct 09 '16 at 19:18
4

In C# the preferred way is through properties rather than getX() and setX() methods. Also, note that C# does not require that properties have both a get and a set - you can have get-only properties and set-only properties.

public boolean MyProperty
{
    get { return something; }
}

public boolean MyProperty
{
    set { this.something = value; }
}
Zach Johnson
  • 23,678
  • 6
  • 69
  • 86
4

First let me try to explain what you wrote:

// private member -- not a property
private string name;

/// public method -- not a property
public void setName(string name) {
   this.name = name;
}

/// public method -- not a property
public string getName() {
   return this.name;
}

// yes it is property structure before .Net 3.0
private string name;
public string Name {
   get { return name; }
   set { name = value; }
}

This structure is also used nowadays but it is most suitable if you want to do some extra functionality, for instance when a value is set you can it to parse to capitalize it and save it in private member for alter internal use.

With .net framework 3.0

// this style is introduced, which is more common, and suppose to be best
public string Name { get; set; }

//You can more customize it
public string Name
{
    get;
    private set;    // means value could be set internally, and accessed through out
}

Wish you better luck in C#

John
  • 15,990
  • 10
  • 70
  • 110
Waqas Raja
  • 10,802
  • 4
  • 33
  • 38
3

As mentioned, all of these approaches result in the same outcome. The most important thing is that you pick a convention and stick with it. I prefer using the last two property examples.

Jeff LaFay
  • 12,882
  • 13
  • 71
  • 101
2

like most of the answers here, use Automatic properties. Intuitive, less lines of code and it is more clean. If you should serialize your class, mark the class [Serializable]/ with [DataConract] attribute. And if you are using [DataContract] mark the member with

[DataMember(Name="aMoreFriendlyName")]
public string Name { get; set; }

Private or public setter depends on your preference.

Also note that automatic properties require both getters and setters(public or private).

/*this is invalid*/
public string Name 
{ 
    get; 
   /* setter omitted to prove the point*/
}

Alternatively, if you only want get/set, create a backing field yourself

tplaner
  • 8,363
  • 3
  • 31
  • 47
ram
  • 11,468
  • 16
  • 63
  • 89
0

Which one should I use, and what are the caveats or subtleties involved with each approach?

When going with properties there is one caveat that has not been mentioned yet: With properties you cannot have any parametrization of your getters or setters.

For example imagine you want to retrieve a list items and want to also apply a filter at the same time. With a get-method you could write something like:

obj.getItems(filter);

In contrast, with a property you are forced to first return all items

obj.items

and then apply the filter in the next step or you have to add dedicated properties that expose items filtered by different criteria, which soon bloats your API:

obj.itemsFilteredByX
obj.itemsFilteredByY

What sometimes can be a nuisance is when you started with a property, e.g. obj.items and then later discovered that getter- or setter-parametrization is needed or would make things easier for the class-API user. You would now need to either rewrite your API and modify all those places in your code that access this property or find an alternative solution. In contrast, with a get-method, e.g. obj.getItems(), you can simply extend your method's signature to accept an optional "configuration" object e.g. obj.getItems(options) without having to rewrite all those places that call your method.

That being said, (auto-implemented) properties in C# are still very useful shortcuts (for the various reasons mentioned here) since most of the time parametrization may not be needed – but this caveat stands.

Felix K.
  • 14,171
  • 9
  • 58
  • 72