8

I've always been told to encapsulate ANY and ALL properties from a class...

This is right:

private string propertyName;
public string PropertyName
{
    get { return propertyName; }
    set { propertyName = value; }
}

And this is WRONG

Public string PropertyName;

I can't see where is the need of encapsulation... the first code, for me, is just useless redundant code... there's no need for encapsulation of that field...

So if anyone can justify the encapsulation ON THIS SCENARIO. (I can understand on other scenarios).

middus
  • 9,103
  • 1
  • 31
  • 33

8 Answers8

11

For the most part, a public field would be okay in practice. After all, if you later needed to make it read-only from outside, or add behavior to its setter, you could just change it to a property then. So you could make it a public field today, and change it later if you need to. Right?

The thing is, there are some cases where you can't safely change it later:

  • If you compile Foo.dll with a public field, and someone builds Bar.dll that references Foo.dll, you cannot later drop in a new version of Foo.dll with that field changed to a property. You would have to have that other person rebuild Bar.dll against your new Foo.dll. For some shops, this isn't a problem; for others, it could be a huge problem.
  • If you write any Reflection code, reflecting against fields is very different from reflecting against properties. So if you later changed your field to a property, your Reflection code would break.

How important are either of these scenarios? Probably not very. But it's easier to preemptively write

public string PropertyName { get; set; }

than it is to clean up the mess if you do have to change it later.

And there's no performance cost. The JIT compiler will inline the getter and setter anyway. So it costs nothing and gives some benefit; at that point, why not use a property?

Joe White
  • 94,807
  • 60
  • 220
  • 330
  • You've understood my question! But I cant see a problem with that DLL's... the signature will remain the same, the acess to the field will remain the same, there's no code change at all... It will work on any case, but if you don't update the library you will not get any "new validation" or anything... I don't know what is a "Reflection code", but thanks, I will do some research about it. – Gabriel Marcondes de Oliveira Dec 01 '11 at 20:10
  • 3
    the code you write looks the same but actually properties compile into separate PropertyName_get() and propertyName_set() methods - the compiler just hides that detail from you.... at least its hidden until you try to convert a field to a property and other DLLs stop working – Robert Levy Dec 01 '11 at 20:19
  • 1
    @RobertLevy, technically it's `get_PropertyName` and `set_PropertyName` (the `get_` is at the beginning). But yeah, that's exactly the reason -- the JIT will see you trying to do a `ldfld` instruction, and there's no field of that name, so it throws a runtime error. – Joe White Dec 01 '11 at 20:26
4

Your main complaint is the verbosity of the first implementation. Your syntax reads as C# to me so public String PropertyName{get;set;} would be a less verbose but equivalent statement. The usefulness is that you can change the backing implementation of the property without changing the usages. The coding style for fields vs properties usually varies so it would result at least in a refactoring of the interface which could be painful if it is exposed to others.

Yes it is overkill most of the time.

Update: Based on the comments below I'll add a little bit about the differences the compiler notes between fields and properties. You can't use a property as a ref or out argument, and as noted below by Robert Levy while the code reads the same there is a function call secreted in by the compiler so you do need to recompile dependent assemblies. You can put a property into an interface but not a field. So there are some pros and cons.

Sign
  • 1,919
  • 18
  • 33
  • It's a nice tip... but i really don't get the point... – Gabriel Marcondes de Oliveira Dec 01 '11 at 20:03
  • @GabrielMarcondesdeOliveira A field says I have a thing, the property says I can get you a thing. It is a slight difference in meaning. – Sign Dec 01 '11 at 20:12
  • @Sign So the code is more "semanticaly correct"? – Gabriel Marcondes de Oliveira Dec 01 '11 at 20:16
  • @GabrielMarcondesdeOliveira more or less. When I was last writing C# regularly the people who had been C++ programmers initially wrote C# that had public fields and the long time java programmers initially wrote C# that had get and set methods but we all converged on properties and more specifically auto properties as the C# way of doing things. – Sign Dec 01 '11 at 20:21
2

Because you can change, e.g., set later on to perform validation. This is not possible with public string PropertyName so you'll be stuck with a public attribute forever.


As others have said in their answers, you can remove some of the cruft using this syntax:

public string PropertyName { get; set; }
Community
  • 1
  • 1
middus
  • 9,103
  • 1
  • 31
  • 33
  • later is later, is another scenario, not this one... if i don't need validation? why i'll be stuck forever? I can encapsulate any public property without any problem! – Gabriel Marcondes de Oliveira Dec 01 '11 at 20:00
  • No later is part of this scenario, because code needs to be flexible. If you add `get/set` later on, your users (i.e. other classes using your class) need to be changed or at least recompiled (I'm not that much into C#, sorry). If you can't do that, e.g. because it's out of your control (other company, department, project etc.), you'll be stuck or have to break their software. – middus Dec 01 '11 at 20:10
  • The code is already flexible as is... Don't get your point... the interface will remain the same... So I don't need to change the code that references the field or property... The signature is the same i think. – Gabriel Marcondes de Oliveira Dec 01 '11 at 20:20
  • Just because it looks similar does not make it the same. See the comments in Joe White's answer: http://stackoverflow.com/a/8347466/9371 – middus Dec 01 '11 at 20:23
2

It looks redundant but this is meant to give you future flexibility without breaking other classes that use your class.

If you start with public string PropertyName; but later switch to defining a real property, other classes using your will have to be recompiled (even though their actual code won't have to change).

In newer versions of C#, there is a shorthand for this: public string MyProperty {get; set; } which behind the scenes creates the private member that you aren't (currently) using.

Robert Levy
  • 28,747
  • 6
  • 62
  • 94
1

You encapsulate to ensure data integrity. For example, if you have an age attribute for class person you wouldn't want someone to store a large number like 19348 into this variable. If you use encapsulation you can validate this number and do error handling when a user tries to do something like this. And by "a user" I mean another programmer using your class.

Boundless
  • 2,444
  • 2
  • 25
  • 40
1

One more example. You can easy override a property while inheritance.

class Base
{
    public virtual string PropertyName { get; set; }
}

class Derived : Base
{
    public override string PropertyName
    {
        get
        {
            return base.PropertyName + " Something";
        }
        set
        {
            base.PropertyName = value;
        }
    }
}
Alex Kovanev
  • 1,858
  • 1
  • 16
  • 29
0

Encapsulating allows you to change the implementation details without changing the interface to the class (meaning no code that uses the class needs to change). For instance, you can later add some sort of validation, or other logic that changes things internally as a side effect of that property change, or even replaces the underlying storage for the property), all without having to change anything that uses this class.

It's a good habit to always encapsulate data, even if you don't see the need now (and particularly because most modern IDEs will auto-generate the getters and setters for you).

Ken White
  • 123,280
  • 14
  • 225
  • 444
0

I think the general idea behind encapsulating accessor methods is to make the code more flexible in the future (i.e. good programming practice).

If you need to change implementation details, fire-off notifications when certain properties change, keep track of how many times a property is accessed, it will allow you to modify the encapsulating methods without impacting other code.

If you're writing code which is likely to be enhanced in the future, it's worth the extra work, even at the cost of additional boiler-plate verbiage.

Jin Kim
  • 16,562
  • 18
  • 60
  • 86