Why ever use fields instead of properties?

18,145

Solution 1

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.

Solution 2

Just try using a Property when using ref/out args:

someObject.SomeMethod(ref otherObject.SomeProperty);

It won't compile.

Solution 3

If you want to have something readonly you pretty much have to use a field as there is no way to tell an automatic property to generate a read-only field.

I do this quite often.

Contrived example:

class Rectangle
{
   private readonly int _width;
   private readonly int _height;

   public Rectangle(int width, int height)
   {
      _width = width;
      _height = height;
   }

   public int Width { get { return _width; } }
   public int Height { get { return _height; } }
}

This means nothing inside of Rectangle can alter the width or height after construction. If one tries to the compiler will complain.

If I instead had used an automatic property with a private setter the compiler wouldn't protect me from myself.

Another reason I see is, if a piece of data doesn't have to be exposed (stay private) why make it a property?

Solution 4

Properties are a wonderful thing -- but there is overhead associated with property access. Not necessarily a problem, but something to be aware of.

Avoiding Overuse of Property Getters and Setters

Most people don't realize that property getters and setters are similar to methods when it comes to overhead; it's mainly syntax that differentiates them. A non-virtual property getter or setter that contains no instructions other than the field access will be inlined by the compiler, but in many other cases, this isn't possible. You should carefully consider your use of properties; from inside a class, access fields directly (if possible), and never blindly call properties repeatedly without storing the value in a variable. All that said, this doesn't mean that you should use public fields!

Source: http://dotnet.sys-con.com/node/46342

Solution 5

While I agree with what I perceive as the "intent" in David Basarab's statement : "There is no reason to publicly expose fields," I'd like to add a slightly different emphasis :

I'd modify the quote from David above to read : "There is no reason to publicly expose fields ... outside a class ... except through the conscious choice of encapsulating the fields in Properties through which access is rigorously controlled.

Properties are not simply a "veneer" of syntax over Fields "tacked onto" C# : they are a fundamental language feature designed for good reasons including :

  1. controlling what is exposed and not exposed outside classes (encapsulation, data hiding)

  2. allowing certain actions to be performed when a Property is accessed or set : actions that are best expressed in the Property 'get and 'set, rather than being "elevated" to externally defined methods.

  3. Interfaces by design cannot define 'fields : but can define Properties.

Good OO Design means making conscious choices about "state" :

  1. local variable fields : what state is private to a method and transient : local variables typically only valid within the scope of a method body, or even with as "narrow a lifespan" as within the scope of something like a 'for loop. Of course you can regard parameter variables in a method as "local" also.

  2. class instance fields : what state is private to a class, and has independent existence for each instance of a class, but is most likely required to be used in several places in the class.

  3. static instance fields : what state will be a property of the class only, independent of the number of instances of the class.

  4. state deliberately and consciously exposed "outside" the class : the key idea being that there is at least one level of indirection interposed between the class and "consumers" of the data the class exposes. The "flip side" of "exposure" is, of course, the conscious intention of hiding (encapsulating, isolating) implementation code.

    a. via public properties : all aspects of this well-covered in all the other answers here

    b. via indexers

    c. via methods

    d. public static variables are usually found in utility classes, which are often static classes.

Suggest you review : MSDN on 'Fields ... MSDN on Properties ... MSDN on Indexers

Share:
18,145

Related videos on Youtube

Matthew
Author by

Matthew

Updated on March 13, 2020

Comments

  • Matthew
    Matthew about 4 years

    I'm fairly new to C#, and I think properties are a wonderful thing. So wonderful, in fact, that I can't see any real advantage to using fields, instead. Even for private fields, it seems like the flexibility and modularity that properties offer can at best save you serious headaches, and at worst have no effect at all.

    The only advantage I can see for fields is that you can initialize them inline. But most of the time, you want to initialize them in the constructor, anyway. If you aren't using inline initialization, is there any reason not to use properties all the time?

    Edit: Some people have brought up the need to back up properties with fields (either explicitly or automatically). Let clarify my question: Is there any reason to use fields except to back up properties? I.e., is there any time that SomeType someField; is preferable to SomeType SomeProperty { get; set; }?

    Edit 2: DanM, Skurmedel, and Seth all gave really useful answers. I've accepted DanM's, as it is the most complete, but if someone were to summarize their responses into a single answer, I'd be happy to accept it.

    • user73993
      user73993 over 14 years
    • Mark Byers
      Mark Byers over 14 years
      No, I think this is a very excellent question which is also very subtle indeed. Definitely different.
    • jyoungdev
      jyoungdev almost 14 years
      This is not a duplicate. The other question asks "What is the difference between A and B"; this one acknowledges the difference between A and B and asks "Does A render B obsolete?"
    • hypehuman
      hypehuman over 8 years
      In C# 6.0, auto-properties will support inline initialization and the readonly keyword, which makes this question even more pertinent.
    • Sebastian Werk
      Sebastian Werk almost 6 years
      @hypehuman I know inline initialization SomeType SomeProperty { get; } = new SomeType(); but what do you mean with readonly keyword?
    • hypehuman
      hypehuman almost 6 years
      @SebastianWerk Whoops, there is no such thing. I must have been confused back then when I read the announcement. Read-only properties are implicitly determined by having no setter; they don't use an explicit readonly keyword.
  • Hannoun Yassir
    Hannoun Yassir over 14 years
    You should mention that the compiler creates a field for each auto property
  • t0mm13b
    t0mm13b over 14 years
    Not alone that, publicly exposing the fields is against the OOP paradigm in terms of hiding information within a concrete class...
  • Mark Byers
    Mark Byers over 14 years
    I think that the posters point is: even your _name field in the example you gave could be a private auto-implemented property. In theory you don't actually need to know about the fields at all, they're just an implementation detail of how properties work, they could be completely hidden from the developer by the compiler as implementation details, just like CPU registers are.
  • devuxer
    devuxer over 14 years
    @Mark, you are technically correct, but using a private property as a "backing property" would seem to violate convention, which would make the intent of your code unclear to those who need to read or maintain it. It also creates a naming issue. If the public property is Name, what would you call the private property? If you call it _name or _Name, other people will reading your code will likely form incorrect conclusions about whether that variable is a property or a field. That said, maybe one day the distinction between properties and fields will disappear.
  • Skurmedel
    Skurmedel over 14 years
    Why would you want to have properties all the time?! Or do you mean a modifier on the field that told it to make a property (whatever that would look like ;))?
  • Mark Byers
    Mark Byers over 14 years
    Why do you want to have two different syntaxes for "this is a member"? ;-)
  • Matthew
    Matthew over 14 years
    @DanM: Thanks for your answer. What I'm really getting at, though, is the difference between SomeType someField; and SomeType SomeProperty { get; set; }. Behind the scenes, SomeProperty may have auto-implemented fields, but from programmer's perspective, is there any reason to prefer someField? I edited my original question to clarify this.
  • Mark Byers
    Mark Byers over 14 years
    Actually you wouldn't need a modifier if everything were a property. You wouldn't even need to say public int Foo { get; set; }. Just saying public int Foo; would be fine because if everything is a property, that would be safe, and the code is more concise. But obviously this can't ever happen in C#. The decision to have two different things 'fields' and 'properties' is set in stone and cannot be changed.
  • Skurmedel
    Skurmedel over 14 years
    I don't quite see how that would allow for lazy loading, or validation?
  • Mark Byers
    Mark Byers over 14 years
    @Skurmedel: I'm not saying ditch the syntax for properties, I'm saying if the syntax currently used for "field" actually meant "auto-implemented property" then you wouldn't need fields at all. I'm also saying it's totally impractical to make this change, at least for C#. :)
  • Skurmedel
    Skurmedel over 14 years
    No I understand what you mean, but where would you store stuff if you needed to do some validation or similar, in another property?
  • Matthew
    Matthew over 14 years
    This is good to know. Why can't you do public readonly int Width { get; set; }?
  • Skurmedel
    Skurmedel over 14 years
    No idea. I can only guess; maybe it was cut in favour of other features, or they didn't see the need. You'll have to ask Eric Lippert about that :)
  • Mark Byers
    Mark Byers over 14 years
    @Skurmedel: Yeah - it would be the exact same code that you write now, only the backing field would actually be a backing property! Did I remember to mention that using properties where people expect to see fields would confuse everyone? Hmmm... Yep I did! ;)
  • Skurmedel
    Skurmedel over 14 years
    Hehe ok I see what you mean :)
  • Skurmedel
    Skurmedel over 14 years
    Since you can only fiddle on readonly fields in the constructor (or when declaring them), I can't quite imagine what a good syntax for declaring a readonly property would look like either.
  • devuxer
    devuxer over 14 years
    @Matthew, I updated my answer to address the update to your question.
  • Mark Byers
    Mark Byers over 14 years
    @Dan: "That said, maybe one day the distinction between properties and fields will disappear." I think so too. But it's going to take generations probably. We only just got ourselves weaned off <s>assembler</s> C++ recently.
  • Mark Byers
    Mark Byers over 14 years
    @Dan: "(according to convention for properties)" I think the naming convention is more concerned with whether the field/property is public than whether or not it is a property. If you had public fields, they'd probably have a capital letter too, whereas private properties would not.
  • Mark Byers
    Mark Byers over 14 years
    "A non-virtual property getter or setter that contains no instructions other than the field access will be inlined by the compiler" The case he is referring to (private auto-implemented properties) will fall into this category, so no performance impact according to this.
  • devuxer
    devuxer over 14 years
    @Mark, I agree that public vs. private is the important distinction, but if you go around writing private string _name { get; set; }, people will look at you funny (and I have a feeling StyleCop would not be amused) :)
  • Mark Byers
    Mark Byers over 14 years
    @Matthew: "Why can't you do public readonly int Width { get; set; }" I think this is another excellent question. :) I'd like to know the answer to this too.
  • Mark Byers
    Mark Byers over 14 years
    I don't think this really answers his question. He wants to know why fields are recommended over properties in certain situations.
  • Matthew
    Matthew over 14 years
  • Eric Lippert
    Eric Lippert over 14 years
    The statement that there are no reasons to publically expose fields is incorrect; were that the case, the feature would be illegal. There are a number of good reasons to publically expose a field. For example, building a mutable struct to be used in an interop scenario with a legacy COM object. This is particularly germane when the fields of the object are passed as "ref" or "out" arguments to a legacy COM object method.
  • Erup
    Erup almost 14 years
    Thats enough for me. The reasons of why exposing properties and keeping the variables for private purposes (following OO conventions) are clear! Another good explanation is exposed by @BillW.
  • jyoungdev
    jyoungdev almost 14 years
    The default property may be made virtual so it can be overridden, and you can control get and set access independently (e.g. make the get accessor public and the set accessor protected). What if you don't need these at first, but you may need them later? Then you could start with a field and use a property later, unless you are accessing fields or properties via reflection. So... the advantage is there only sometimes.
  • Nathan
    Nathan over 13 years
    I second the use of fields when dealing the use of "ref" or "out". It takes a ton of extra code to set up for transferring into what is essentially a DTO. So I just changed the properties to fields. Why make things complicated?
  • Brandon Barkley
    Brandon Barkley over 8 years
    Worth also noting is that if you convert from field to property later because requirements change, anything that references the field has to be recompiled as well.
  • Matthew
    Matthew over 8 years
    C# 6.0 now supports readonly properties! object MyProp { get; } This property can be set inline (object MyProp { get; } = ...)or in the constructor, but nowhere else (just like readonly fields).
  • Gaspa79
    Gaspa79 over 7 years
    This is now possible with C#6
  • Sedat Kapanoglu
    Sedat Kapanoglu over 3 years
    It's now possible even more easily with C# 9.0: public int Width { get; init; }
  • BlueStaggo
    BlueStaggo almost 3 years
    You can now do private int x { get; set; } = 7;. I believe that's what Gaspa is saying.