Why Use Simple Properties Instead of Fields in C#

Why use simple properties instead of fields in C#?

Using properties has a couple of distinct advantages:

  • It allows for versioning if later you need extra logic. Adding logic to the getter or setter won't break existing code.
  • It allows data binding to work properly (most data binding frameworks don't work with fields).

In addition, there are almost no disadvantages. Simple, automatic properties like this get inlined by the JIT compiler, so there is no reason not to use them.

Also, you mentioned:

Other than these fairly rare cases, changing Foo to be a computed property later results in 0 lines of code changed.

This doesn't require your code to be changed, but it does force you to recompile all of your code. Changing from a field to a property is a breaking API change which will require any assembly which references your assembly to be recompiled. By making it an automatic property, you can just ship a new binary, and maintain API compatibility. This is the "versioning" advantage I mentioned above...

Why do we use fields & properties instead of just a variable?

Just for encapsulation principle. For hinding concrete implementaiton, and plus, you have an opportunity (in this case) to add additional code inside get/set.

If you don't need addittional code, you can use just

public string Name{get;set;}

or use fileds, as you would like. But using properties is a guideline offered by Microsoft.

So basically all, follow it.

Why ever use fields instead of properties?

Typically, properties need a backing field unless they are simple getter/setter "automatic properties".

So, if you're just doing...

public string Name { get; set; } // automatic property

...you don't need a field, and I agree, no reason to have one.

However, if you're doing...

public string Name
{
get { return _name; }
set
{
if (value = _name) return;
_name = value;
OnPropertyChange("Name");
}
}

...you need that _name backing field.

For private variables that don't require any special get/set logic, it's really a judgment call whether to do a private automatic property or just a field. I usually do a field, then, if I need it to be protected or public, I will change it to an automatic property.

Update

As noted by Yassir, if you use automatic properties, there's still a field lurking behind the scenes, it's just not something you actually have to type out. So, the bottom line is: properties don't store data, they provide access to data. Fields are what actually hold the data. So, you need them even if you can't see them.

Update 2

Regarding your revised question...

is there any time that SomeType someField; is preferable to SomeType SomeProperty { get; set; }?

...one thing that comes to mind: If you have a private field, and (according to convention for private fields) you call it _name, that signals to you and anyone reading your code that you are working directly with private data. If, on the other hand, you make everything a property, and (according to convention for properties) call your private property Name, now you can't just look at the variable and tell that it is private data. So, using only properties strips away some information. I haven't tried working with all properties to gauge whether that is crucial information, but something is definitely lost.

Another thing, more minor, is that public string Name { get; set; } requires more typing (and is a little messier) than private string _name.

What is the difference between a field and a property?

Properties expose fields. Fields should (almost always) be kept private to a class and accessed via get and set properties. Properties provide a level of abstraction allowing you to change the fields while not affecting the external way they are accessed by the things that use your class.

public class MyClass
{
// this is a field. It is private to your class and stores the actual data.
private string _myField;

// this is a property. When accessed it uses the underlying field,
// but only exposes the contract, which will not be affected by the underlying field
public string MyProperty
{
get
{
return _myField;
}
set
{
_myField = value;
}
}

// This is an AutoProperty (C# 3.0 and higher) - which is a shorthand syntax
// used to generate a private field for you
public int AnotherProperty { get; set; }
}

@Kent points out that Properties are not required to encapsulate fields, they could do a calculation on other fields, or serve other purposes.

@GSS points out that you can also do other logic, such as validation, when a property is accessed, another useful feature.

Properties vs. Fields: Need help grasping the uses of Properties over Fields

You should not worry about the extra code needed for accessing fields via properties, it will be "optimized" away by the JIT compiler (by inlining the code). Except when it is too large to be inlined, but then you needed the extra code anyway.

And the extra code for defining simple properties is also minimal:

public int MyProp { get; set; } // use auto generated field.

When you need to customize you can alway define your own field later.

So you are left with the extra layer of encapsulation / data protection, and that is a good thing.

My rule: expose fields always through properties

Is there any reason to use very simple properties over fields?

In this case if you aren't going to add some logic to the getter or setter then I would use static fields. Performance will be the same.

But if later you need extra logic when you set ot get values then it preffer to use properties because it allows for versioning and it gives you Encapsulation according to OOP principles. Don't care about performance

For Monitoring property you can use Auto-Implemented Property like

public static bool Monitoring { get; set; }

but in this case you need to implement a static constructor (thanks to @Mafii)

    static General()
{
Monitoring = false;
}

or if you use C# 6.0 then just:

public static bool Monitoring { get; set; } = false;

What's the reason for peoples to use properties with get; set; instead of fields?

The main reason is encapsulation - the value can only be changed trough the corresponding properties, and this continues to be the case even if you later decide that the property shouldn't just return a value. Maybe you find that you'll want to fire an event when a value changes? If you've got a property, that's very easy. If you've got a public field, you need to make a breaking change.

In addition, properties can be virtual or declared in interfaces. And they can be declared read-only.

Oh, and it helps in debugging: You can set a breakpoint on the "set", if you want to know who is changing your value (unexpectedly).

Why do we use fields & properties instead of just a variable?

Just for encapsulation principle. For hinding concrete implementaiton, and plus, you have an opportunity (in this case) to add additional code inside get/set.

If you don't need addittional code, you can use just

public string Name{get;set;}

or use fileds, as you would like. But using properties is a guideline offered by Microsoft.

So basically all, follow it.

Why aren't simple properties optimized to fields?


for (int i = 0; i < 100000000; i++)
y += t.X;

This is very difficult code to profile. You can see that when looking at the generated machine code with Debug + Windows + Disassembly. The x64 code looks like this:

0000005a  xor         r11d,r11d                           ; i = 0
0000005d mov eax,dword ptr [rbx+0Ch] ; read t.X
00000060 add r11d,4 ; i += 4
00000064 cmp r11d,5F5E100h ; test i < 100000000
0000006b jl 0000000000000060 ; for (;;)

This is heavily optimized code, note how the += operator completely disappeared. You allowed this to happen because you made a mistake in your benchmark, you are not using the computed value of y at all. The jitter knows this so it simply removed the pointless addition. The increment by 4 needs an explanation as well, this is a side-effect of a loop unrolling optimization. You'll see it used later.

So you must make a change to your benchmark to make it realistic, add this line at the end:

sw.Stop();
Console.WriteLine("{0} msec, {1}", sw.ElapsesMilliseconds, y);

Which forces the value of y to be computed. It now looks completely different:

0000005d  xor         ebp,ebp                             ; y = 0
0000005f mov eax,dword ptr [rbx+0Ch]
00000062 movsxd rdx,eax ; rdx = t.X
00000065 nop word ptr [rax+rax+00000000h] ; align branch target
00000070 lea rax,[rdx+rbp] ; y += t.X
00000074 lea rcx,[rax+rdx] ; y += t.X
00000078 lea rax,[rcx+rdx] ; y += t.X
0000007c lea rbp,[rax+rdx] ; y += t.X
00000080 add r11d,4 ; i += 4
00000084 cmp r11d,5F5E100h ; test i < 100000000
0000008b jl 0000000000000070 ; for (;;)

Still very optimized code. The weirdo NOP instruction ensures that the jump at address 008b is efficient, jumping to an address that's aligned to 16 optimizes the instruction decoder unit in the processor. The LEA instruction is a classic trick to the let the address generation unit generate an addition, allowing the main ALUs to perform other work at the same time. No other work to be done here but could have if the loop body was more involved. And the loop was unrolled 4 times to avoid branch instructions.

Anyhoo, now you are actually measuring real code, instead of removed code. Result on my machine, repeating the test 10 times (important!):

y += t.X: 125 msec
y += t.Y: 125 msec

Exactly the same amount of time. Of course, it should be that way. You don't pay for a property.

The jitter does an excellent job of generating quality machine code. If you get a strange result then always check your test code first. It is the code most likely to have a mistake. Not the jitter, it has been thoroughly tested.



Related Topics



Leave a reply



Submit