vrwim
vrwim

Reputation: 14380

Should I use a field or a property?

First of all, I have read the question asking for the difference between fields and properties and I know what it is used for.

Now on to my question, I wanted to create a property where I am sure that get and set will both be empty, so I do get; set;. All good and well. But now I realised that I have just made a public field with a capital name, it is in all ways identical.

Even the argument of it being used so future code does not depend on implementation cannot be said, as I can simply make this a property and implement a getter or a setter. The semantics of a field and a property are identical outside the class it is defined in.

So my question is, should I use a field or a property when a property would simply use get;set;?

So this:

public IEnumerable<string> Products;

is identical in all ways to this:

public IEnumerable<string> Products { get; set; }

Upvotes: 2

Views: 474

Answers (3)

Jon Skeet
Jon Skeet

Reputation: 1503479

should I use a field or a property when a property would simply use get;set;?

Use a property... for the practical reasons below, and for the philosophical reasons that properties expose a state API, whereas fields expose a state implementation detail.

The semantics of a field and a property are identical outside the class it is defined in.

That's not true.

  • The difference is visible via reflection, which is often very important. For example, many binding frameworks won't use fields, only properties.
  • You can pass a mutable field by ref, but not a property - so changing a field to a property breaks source compatibility. (Code using SomeMethod(ref x.Products) will become invalid when Products becomes a property.)
  • Changing a field to a property also breaks binary compatibility, so if assembly X was built against assembly Y v1.0, and you change a field to a property for assembly Y v1.1, then you'd need to rebuild assembly X or it would fail to execute correctly
  • If you have a mutable value type (please don't do this) then writing foo.Location.X = 10 works when Location is a field (because x.Location is classified as a variable) whereas it doesn't when Location is a property (because then the expression x.Location is classified as a value). If you have a method (in your evil mutable type) which mutates the value instead, then foo.Location.DoSomething() will compile in both cases, but have a different effect. Fun for all the family.

Upvotes: 9

Avinash Jain
Avinash Jain

Reputation: 7616

Its depend on the situation. I'll prefer to use the property over the field. You have mentioned that public IEnumerable<string> Products; and public IEnumerable<string> Products { get; set; } are same, but in actual they are not. During compilation the property will get converted into two methods (i.e. get_Products() and set_Products()).

The advantage of property is to allows you to specify the custom code before assigning and returning the data, this is not possible with the field. Check the example below

public IEnumerable<string> Products
        {
            get
            {
                if(DateTime.Now.Date > Convert.ToDateTime("01-01-2016"))
                {
                    //Return future product
                    return new List<string>();
                }
                else
                {
                    // return current products
                    return new List<string>() { "testing" };
                }
            }
            set
            {
                if (DateTime.Now.Date > Convert.ToDateTime("01-01-2016"))
                {
                    //ignore assign product
                    Products = new List<string>();
                }
                else
                {
                    // add assign product
                    Products = value;
                }
            }
        }

Upvotes: 1

Dai
Dai

Reputation: 155658

Using the auto-property syntax is preferable because it creates a read/write property with a private backing field, thus allowing you to change the implementation (from a private scalar field to a dictionary entry or another backend with some other custom logic), thus freeing the "class's interface" (not the same thing as an interface) from its implementation.

Note that for collection member properties, it is advisable to make their setters private, like so:

public IEnumerable<String> Products { get; private set;}

...that way only the containing class can alter it.

Another alternative is the private readonly field, in C# 6 you can use auto-implemented properties with readonly backing fields like so:

public IEnumerable<String> Products { get; } = SomeSource.GetProducts();

Upvotes: 0

Related Questions