5

Possible Duplicate:
What is Difference between Property and Variable in C#

I started working with C# a few weeks ago, and this is something that has really been bugging me. C# allows these so-called 'magic' getters and setters, also known as 'syntactical sugar'. So, I can do something like this:

public int myInt { get; set; }

But from an encapsulation standpoint, this is pointless. For one, the data member is public, and I can get/set it using the dot operator. However, if I do this:

private int myInt { get; set; }

I can't access it at all, as myInt is inaccessible due to protection level. What is this actually doing? I thought this was supposed to be an easy way to accomplish data encapsulation, so I wouldn't have to do this:

private int myInt;
public void setMyInt(int i) { myInt = i; }
public int getMyInt() { return myInt; }

But it's not. As near as I can tell, I'm just making these variables public. I thought maybe I would be able to do something like

public int myInt { get; }

So the client could get it, but not set it, but no, public access is still allowed. So what gives?

EDIT I'm not trying to do anything specific, I just want to understand how this actually works. To clarify:

Making the variable public doesn't accomplish encapsulation, especially when I can access it with the dot operator. Writing getters and setters for a private variable allows you to make changes to the variable, but gives you greater control over how that actually happens.

Community
  • 1
  • 1
Mike G
  • 4,232
  • 9
  • 40
  • 66
  • 1
    This question has already been discussed here: http://stackoverflow.com/questions/4142867/what-is-difference-between-property-and-variable-in-c-sharp – Zak Jul 25 '12 at 14:35
  • 1
    @Zak, that's what I was looking for. Please feel free to vote to close as dupe. – Mike G Jul 25 '12 at 14:40

5 Answers5

8

The purpose is that you maintain encapsulation through future modification.

If you initially write your class using automatic getters and setters:

public int Count { get; set; }

Then it'll maintain precisely the same external interface if you then change it to

public int Count {
    get { /* very complicated logic */ }
    set { /* even more complicated logic */ }
}

The automatic ones are just to help you with the simple properties at first.

Matthew Walton
  • 9,809
  • 3
  • 27
  • 36
6

You're trying to write

public int MyInt { get; private set; }

EDIT: The point of auto-implemented properties is not to provide additional encapsulation, but to avoid fields.
If you make a class with a public field (publit int MyInt;), and someone uses that field, you cannot change it to a property later, or you'll break any compiled assemblies that use it.

Using an auto-property gives you the same simplicity and concision as a field, but allow you to later replace it with a full-blown property (containing additional logic) without breaking anything.

SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
  • No, I'm just trying to understand what's actually going on here, I'm not trying to do anything specific. – Mike G Jul 25 '12 at 14:35
  • What precisely don't you understand? – SLaks Jul 25 '12 at 14:35
  • I'd say the point of auto-implemented properties is primarily to just reduce the amount of boilerplate code you need to write for a trivial property. – Jon Skeet Jul 25 '12 at 14:40
  • @JonSkeet: Yes. I meant as opposed to fields, which I suspect is what the OP meant. – SLaks Jul 25 '12 at 14:42
  • In some instances, making the getter private and the setter public might sense as well. I have found this a useful idiom for dependency injection. There is no way to express this with public field. – chris Jul 25 '12 at 14:45
6

This "magic" getters and setters as you call them, actually end up creating methods just like you would do in Java. So Encapsulation is maintained just that with a cleaner look, IMO.

The properties themselves, even though declared as public int Property {get;set;} for example, actually have a backing field and a getter and a setter method.

See this contrived example:

class A
{
   public int ID {get;set;}
}

Now when you do something like:

A a = new A();
a.ID=5;

The IL code generated looks like this:

A.get_ID:    //getter method
IL_0000:  ldarg.0     
IL_0001:  ldfld       UserQuery+A.<ID>k__BackingField 
IL_0006:  ret         

A.set_ID:   //setter method
IL_0000:  ldarg.0     
IL_0001:  ldarg.1     
IL_0002:  stfld       UserQuery+A.<ID>k__BackingField
IL_0007:  ret         

So yes, doing a.ID=5; looks like it's accessing directly a member variable but it's actually calling a method; in this case, the set_ID method.

Icarus
  • 63,293
  • 14
  • 100
  • 115
0

You are just making it public - if you want to specify private set, you can do something like this:

   int myInt { get; private set; }
naspinski
  • 34,020
  • 36
  • 111
  • 167
0

you can do this, which is very useful:

public int myInt { get; private set; }

marvc1
  • 3,641
  • 3
  • 25
  • 34