Why ever use fields instead of properties?

2019-01-17 19:51发布

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.

13条回答
一夜七次
2楼-- · 2019-01-17 20:07

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

查看更多
爷、活的狠高调
3楼-- · 2019-01-17 20:10

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?

查看更多
Explosion°爆炸
4楼-- · 2019-01-17 20:15

There is no reason to publicly expose fields.

If you public expose a field you can't change the source of the information, from inline defination to configuration file without refactoring.\

You could use a field to hide internal data. I rarely favor that, I only use fields when I am doing something to hide publicly and using it in a property. (i.e. I am not using Automatic property generation)

查看更多
We Are One
5楼-- · 2019-01-17 20:17

As others have noted, you will need a private backing field for properties anyway.

Also there is a speed advantage in using fields over properties. In 99.99 % of the cases it won't matter. But in some it might.

查看更多
戒情不戒烟
6楼-- · 2019-01-17 20:19

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

查看更多
别忘想泡老子
7楼-- · 2019-01-17 20:22

Fields and properties are not interchangeable. I guess what you're saying is accessing private fields through private properties. I do this when it makes sense but for the most part, it's not necessary. The JIT optimizer will inline access to a private field through a private property in most cases anyway. And wrapping a private field in a private property is not considered a breaking change anyway since private members are not a part of your interface.

Personally, I would never expose any protected/public instance fields. It's generally acceptable though to expose a public static field with a readonly modifier as long as the field type is itself immutable. This is often seen with SomeStruct.Empty static fields.

查看更多
登录 后发表回答