First off, I have read through a list of postings on this topic and I don't feel I have grasped properties because of what I had come to understand about encapsulation and field modifiers (private, public..ect).
One of the main aspects of C# that I have come to learn is the importance of data protection within your code by the use of encapsulation. I 'thought' I understood that to be because of the ability of the use of the modifiers (private, public, internal, protected). However, after learning about properties I am sort of torn in understanding not only properties uses, but the overall importance/ability of data protection (what I understood as encapsulation) within C#.
To be more specific, everything I have read when I got to properties in C# is that you should try to use them in place of fields when you can because of:
1) they allow you to change the data type when you can't when directly accessing the field directly.
2) they add a level of protection to data access
However, from what I 'thought' I had come to know about the use of field modifiers did #2, it seemed to me that properties just generated additional code unless you had some reason to change the type (#1) - because you are (more or less) creating hidden methods to access fields as opposed to directly.
Then there is the whole modifiers being able to be added to Properties which further complicates my understanding for the need of properties to access data.
I have read a number of chapters from different writers on "properties" and none have really explained a good understanding of properties vs. fields vs. encapsulation (and good programming methods).
Can someone explain:
1) why I would want to use properties instead of fields (especially when it appears I am just adding additional code
2) any tips on recognizing the use of properties and not seeing them as simply methods (with the exception of the get;set being apparent) when tracing other peoples code?
3) Any general rules of thumb when it comes to good programming methods in relation to when to use what?
Thanks and sorry for the long post - I didn't want to just ask a question that has been asked 100x without explaining why I am asking it again.
1) why I would want to use properties
instead of fields (especially when it
appears I am just adding additional
code
You should always use properties where possible. They abstract direct access to the field (which is created for you if you don't create one). Even if the property does nothing other than setting a value, it can protect you later on. Changing a field to a property later is a breaking change, so if you have a public field and want to change it to a public property, you have to recompile all code which originally accessed that field.
2) any tips on recognizing the use of
properties and not seeing them as
simply methods (with the exception of
the get;set being apparent) when
tracing other peoples code?
I'm not totally certain what you are asking, but when tracing over someone else's code, you should always assume that the property is doing something other than just getting and setting a value. Although it's accepted practice to not put large amounts of code in getters and setter, you can't just assume that since it's a property it will behave quickly.
3) Any general rules of thumb when it
comes to good programming methods in
relation to when to use what?
I always use properties to get and set methods where possible. That way I can add code later if I need to check that the value is within certain bounds, not null etc. Without using properties, I have to go back and put those checks in every place I directly accessed the field.
One of the nice things about Properties is that the getter and the setter can have different levels of access. Consider this:
public class MyClass {
public string MyString { get; private set; }
//...other code
}
This property can only be changed from within, say in a constructor. Have a read up on Dependency Injection. Constructor injection and Property injection both deal with setting properties from some form of external configuration. There are many frameworks out there. If you delve into some of these you will get a good feel for properties and their use. Dependency injection will also help you with your 3rd question about good practice.
When looking at other people's code, you can tell whether something is a method or a property because their icons are different. Also, in Intellisence, the first part of a property's summary is the word Property.
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
While I absolutely dislike directly exposing fields to the public, there's another thing: Fields can't be exposed through Interfaces; Properties can.
There are several reasons why you might want to use Properties over Fields, here are just a couple:
a. By having the following
public string MyProperty { get; private set; }
you are making the property "read only". No one using your code can modify it's value. There are cases where this isn't strictly true (if your property is a list), but these are known and have solutions.
b. If you decide you need to increase the safety of your code use properties:
public string MyProperty
{
get { return _myField; }
set
{
if (!string.IsNullOrEmpty(value))
{
_myField = value;
}
}
}
You can tell they're properties because they don't have (). The compiler will tell you if you try to add brackets.
It's considered good practise to always use properties.
There are many scenarios where using a simple field would not cause damage, but
a Property can be changed more easily later, i.e. if you want to add an event whenever the value changes or want to perform some value/range checking.
Also, If you have several projects that depend on each other you have to recompile all that depend on the one where a field was changed to a property.
Using fields is usually practiced in private classes that is not intended to share data with other classes, When we want our data to be accessible by other classes we use properties which has the ability to share data with other classes through get and set which are access methods called Auto Properties that have access to data in private classes, also you can use both with access modifiers Full Property in the same class allowing the class to use data privately as data field and in the same time link the private field to a property that makes the data accessible to other classes as well, see this simple example:
private string _name;
public string Name
{
get
{
return _name;
}
set
{
_name = value;
}
}
The private string _name is used by the class only, while the Name property is accessible by other classes in the same namespace.
why I would want to use properties instead of fields (especially when it appears I am just adding additional code
You want to use properties over fields becuase, when you use properties you can use events with them, so in a case when you want to do some action when a property changes, you can bind some handlers to PropertyChanging or PropertyChanged events. In case of fields this is not possible. Fields can either be public or private or protected, in case of props you can make them read-only publicly but writable privately.
any tips on recognizing the use of properties and not seeing them as simply methods (with the exception of the get;set being apparent) when tracing other peoples code?
A method should be used when the return value is expected to be dynamic every-time you call, a property should be used when the return value is not that greatly dynamic.
Any general rules of thumb when it comes to good programming methods in relation to when to use what?
Yes, I strongly recommend to read Framework Design guidelines for best practices of good programming.
Properties are the preferred way to cover fields to enforce encapsulation. However, they are functional in that you can expose a property that is of a different type and marshal the casting; you can change access modifiers; they are used in WinForms data binding; they allow you to embed lightweight per-property logic such as change notifications; etc.
When looking at other peoples code, properties have different intellisense icons to methods.
If you think properties are just extra code, I would argue sticking with them anyway but make your life easier by auto-generating the property from the field (right-click -> Refactor -> Encapsulate Field...)
Properties allow you to do things other than set or get a value when you use them. Most notably, they allow you to do validation logic.
A Best Practice is to make anything exposed to the public a Property. That way, if you change the set/get logic at a later time, you only have to recompile your class, not every class linked against it.
One caveat is that things like "Threading.Interlocked.Increment" can work with fields, but cannot work with properties. If two threads simultaneously call Threading.Interlocked.Increment on SomeObject.LongIntegerField, the value will get increased by two even if there is no other locking. By contrast, if two threads simultaneously call Threading.Interlocked.Increment on SomeObject.LongIntegerProperty, the value of that property might get incremented by two, or by one, or by -4,294,967,295, or who knows what other values (the property could be written to use locking prevent values other than one or two in that scenario, but it could not be written to ensure the correct increment by two).
I was going to say Properties (setters) are a great place to raise events like NotifyPropertyChanged, but someone else beat me to it.
Another good reason to consider Properties: let's say you use a factory to construct some object that has a default constructor, and you prepare the object via its Properties.
new foo(){Prop1 = "bar", Prop2 = 33, ...};
But if outside users new up your object, maybe there are some properties that you want them to see as read-only and not be able to set (only the factory should be able to set them)? You can make the setters internal - this only works, of course, if the object's class is in the same assembly as the factory.
There are other ways to achieve this goal but using Properties and varying accessor visibility is a good one to consider if you're doing interface-based development, or if you expose libraries to others, etc.
Related
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Public Fields versus Automatic Properties
I figured this would be answered someplace, but I'm not finding it in the usual places. I was wondering, what is the benefit of doing this
private int _foo;
public int foo {get {return _foo;} set{_foo = value;}}
or
public int foo {get; set;}
over just
public int foo;
I can see the benefit if more complex manipulation was required, but what is the benefit for a simple case like this?
Actually, all the guidelines are about creating reusable libraries. There, when you create a property (using get/set), you also create the opportunity to later add code that is executed when someone gets or sets the value (like adding validation etc.) without changing the external definition of your code (and thus not needing to recompile the other libraries). But this has no value if you always recompile your whole solution and noone else is using the library.
Another benefit from using a property is that you can limit who can get or set the value. For example, everyone can get the value but only derived classes can set it (protected).
This said, it is still the recommendation to use properties always when they are public (as opposed to private fields).
I only expose fields when I need the best possible performance (like accessing the value million times in a row).
So to summarize
Benefits of properties (get/set) over fields:
Ability to add code later on without recompiling assemblies that reference this.
Ability to provide private/protected/internal set and public get (or any other combination).
Public fields are not CLS compliant.
Drawbacks of properties:
Slower to access (both read and write).
Can't pass as ref arguments to methods.
This question was asked many times here.
There is no clear benefit evidence fo these cases (no logic inside property).
Would say more, that using a field, you get some minimal (nano) speed benefit, but not relevant for 99.99% cases.
The guideline defined by MS suggests using properties, for expandibility and maintanability of your code. So following that guideline make easier work for someone that not familiar with the code to reading it.
See this Jon Skeet tutorial or When to use properties instead of functions for discussion of this matter. There is also a billion related questions and resources on this topic, which a Google/SE seach will expose.
I hope this helps.
According to me, using 'get-set' is providing a property. Basically you are implementing the concept of Encapsulation while providing the get-set property to a variable.
Imagine you have public variables in a class to store data.
But, if you need to do data validation, you are unable to do so with public variables in a class. Because you have no control over them. Outsiders, other programmers, anyone who access your project could edit those public variables in a class.
MAINLY, In order to control the access to data in your class we use properties. They are still variables but within the authority of your class. These variables may be from any data type (Eg. String, Int, Bool, Objects, etc)
Properties can be impemented using three main options, based on what/how you want to achieve with a property.
Get - access to the property and retrieve its value
Let - access to the property and update its value
Set - access to the property and used with objects
It's vital that one understands the real use of Get/Set methods. I agree with Tigaran on his comment.
If anyone is going to vode me down, I would like to know the reason!
I think you've answered your own question.
For simple cases like this, there is no real advantage. Automatic get/set methods are created by using the shorthand properties:
public int Foo { get; set; }
For more complex examples where transformation is needed then you have the flexibility to alter things using explicit get and set methods.
We're often told we should protect encapsulation by making getter and setter methods (properties in C#) for class fields, instead of exposing the fields to the outside world.
But there are many times when a field is just there to hold a value and doesn't require any computation to get or set. For these we would all do this number:
public class Book
{
private string _title;
public string Title
{
get => _title;
set => _title = value;
}
}
Well, I have a confession, I couldn't bear writing all that (really, it wasn't having to write it, it was having to look at it), so I went rogue and used public fields.
Then along comes C# 3.0 and I see they added automatic properties:
public class Book
{
public string Title { get; set; }
}
Which is tidier, and I'm thankful for it, but really, what's so different than just making a public field?
public class Book
{
public string Title;
}
In a related question I had some time ago, there was a link to a posting on Jeff's blog, explaining some differences.
Properties vs. Public Variables
Reflection works differently on variables vs. properties, so if you rely on reflection, it's easier to use all properties.
You can't databind against a variable.
Changing a variable to a property is a breaking change. For example:
TryGetTitle(out book.Title); // requires a variable
Ignoring the API issues, the thing I find most valuable about using a property is debugging.
The CLR debugger does not support data break points (most native debuggers do). Hence it's not possible to set a break point on the read or write of a particular field on a class. This is very limiting in certain debugging scenarios.
Because properties are implemented as very thin methods, it is possible to set breakpoints on the read and write of their values. This gives them a big leg up over fields.
Changing from a field to a property breaks the contract (e.g. requires all referencing code to be recompiled). So when you have an interaction point with other classes - any public (and generally protected) member, you want to plan for future growth. Do so by always using properties.
It's nothing to make it an auto-property today, and 3 months down the line realize you want to make it lazy-loaded, and put a null check in the getter. If you had used a field, this is a recompile change at best and impossible at worst, depending on who & what else relies on your assemblies.
Just because no one mentioned it: You can't define fields on Interfaces. So, if you have to implement a specific interface which defines properties, auto-properties sometimes are a really nice feature.
A huge difference that is often overlooked and is not mentioned in any other answer: overriding. You can declare properties virtual and override them whereas you cannot do the same for public member fields.
It's all about versioning and API stability. There is no difference, in version 1 - but later, if you decide you need to make this a property with some type of error checking in version 2, you don't have to change your API- no code changes, anywhere, other than the definition of the property.
Another advantage of auto-implemented properties over public fields is that you can make set accessors private or protected, providing the class of objects where it was defined better control than that of public fields.
There is nothing wrong in making a field public. But remember creating getter/setter with private fields is no encapsulation. IMO, If you do not care about other features of a Property, you might as well make it public.
Trivial properties like these make me sad. They are the worst kind of cargo culting and the hatred for public fields in C# needs to stop. The biggest argument against public fields is future-proofing: If you later decide you need to add extra logic to the getter and setter, then you will have to do a huge refactor in any other code that uses the field. This is certainly true in other languages like C++ and Java where the semantics for calling a getter and setter method are very different from those for setting and getting a field. However, in C#, the semantics for accessing a property are exactly the same as those for accessing a field, so 99% of your code should be completely unaffected by this.
The one example I have seen of changing a field into a property actually being a breaking change at the source level is something like:
TryGetTitle(out book.Title); // requires a variable
To this I have to ask, why TF are you passing some other class's field as a reference? Depending on that not being a property seems like the real coding failure here. Assuming that you can directly write to data in another class that you know nothing about is bad practice. Make your own local variable and set book.Title from that. Any code that does something like this deserves to break.
Other arguments I have seen against it:
Changing a field to a property breaks binary compatibility and requires any code that uses it to be recompiled: This is a concern iff you are writing code for distribution as a closed-source library. In that case, yes, make sure none of your user-facing classes have public fields and use trivial properties as needed. If however you are like 99% of C# developers and writing code purely for internal consumption within your project, then why is recompilation a big concern? Just about any other change you make is going to require recompilation too, and so what if it does? Last I checked, it is no longer 1995, we have fast computers with fast compilers and incremental linkers, even larger recompilations shouldn't need more than a few minutes, and it has been quite some time since I have been able to use "my code's compiling" as an excuse for swordfighting through the office.
You can't databind against a variable: Great, when you need to do that, make it into a property.
Properties have features that make them better for debugging like reflection and setting breakpoints: Great, one you need to use one of those things, make it into a property. When you're done debugging and ready to release, if you don't still need those functionalities, change it back into a field.
Properties allow you to override behavior in derived classes: Great, if you are making a base class where you think such a scenario is likely, then make the appropriate members into properties. If you're not sure, leave it as a field and you can change it later. Yes, that will probably require some recompilation, but again, so what?
So in summary, yes there are some legitimate uses for trivial properties, but unless you are making a closed source library for public release, fields are easy enough to convert into properties when needed, and an irrational fear of public fields is just some object oriented dogma that we would do well to rid ourselves of.
For me, the absolute deal breaker for not using public fields was the lack of IntelliSense, showing the references:
Which is not available for fields.
If you decide later to check that the title is unique, by comparing to a collection or a database, you can do that in the property without changing any code that depends on it.
If you go with just a public attribute then you will have less flexibility.
The extra flexibility without breaking the contract is what is most important to me about using properties, and, until I actually need the flexibility, auto-generation makes the most sense.
One thing you can do with Fields but not with Properties (or didn't used to be able to ... I'll come to that in a moment) is that Fields can be designated as readonly whereas Properties cannot. So Fields give you a clear way of indicating your intention that a variable is there to be set (from within the constructor) at object-instantiation time only and should not be changed thereafter. Yes, you can set a Property to have a private setter, but that just says "this is not to be changed from outside the class", which is not the same as "this is not to be changed after instantiation" - you can still change it post-instantiation from within the class. And yes you can set the backing field of your property to be readonly, but that moves post-instantiation attempts to change it to being run-time errors rather than compile-time errors. So readonly Fields did something useful which Properties cannot.
However, that changes with C# 9, whereby we get this helpful syntax for Properties:
public string Height { get; init; }
which says "this can get used from outside of the class but it may only be set when the object is initialized", whereupon the readonly advantage of Fields disappears.
One thing I find very useful as well as all the code and testing reasons is that if it is a property vs a field is that the Visual Studio IDE shows you the references for a property but not a field.
My pov after did some researches
Validation.
Allow overriding the accessor to change the behaviour of a property.
Debugging purpose. We'll be able to know when and what the property change by setting a breakpoint in the accessor.
We can have a field set-only. For instance, public set() and private get(). This is not possible with the public field.
It really gives us more possibility and extensibility.
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.
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.
Just try using a Property when using ref/out args:
someObject.SomeMethod(ref otherObject.SomeProperty);
It won't compile.
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
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?
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 :
controlling what is exposed and not exposed outside classes (encapsulation, data hiding)
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.
Interfaces by design cannot define 'fields : but can define Properties.
Good OO Design means making conscious choices about "state" :
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.
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.
static instance fields : what state will be a property of the class only, independent of the number of instances of the class.
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
I don't see why you'd use private autoproperties. What advantage is there to
private int Count {get; set;}
over
private int count
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.
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.
Fields are the only place you can store state. Properties are actually just a pair of methods with special syntax that allows them to be mapped to the get or set method depending on how they're being used: if a property modifies or accesses state, that state still has to be stored in a field.
You don't always see the fields. With C# 3 automatic properties, the field is created for you by the compiler. But it's still there. Furthermore, automatic properties have some significant limitations (e.g. no INotifyPropertyChanged support, no business logic in setters) that mean they're often inappropriate, and you need to create an explicit field and a manually defined property anyway.
As per David's answer, you're right if you're talking about an API: you almost never want to make the internal state (fields) part of the API.
The syntax for fields is a lot quicker to write than for properties, so when it's safe to use a field (private to the class) why not use it and save that extra typing? If auto-implemented properties had the nice short concise syntax and you had to do extra work to make a plain old field, people might just start use properties instead. Also, it's a convention now in C#. That's how people think, and it's what they expect to see in code. If you do something different form the normal, you will confuse everyone.
But you could ask why the syntax for fields doesn't create an auto-implemented property instead of a field, so you get the best of both worlds - properties everywhere and a concise syntax.
There's a very simple reason why we still need to have explicit fields:
C# 1.0 didn't have all these nice features that we have now, so fields were a fact of life - you couldn't really live without them. Lots and lots of code relies on fields and properties being visibly different things. It simply cannot be changed now without breaking tons of code.
I would suspect also that there are performance implications, but perhaps that can be solved by the jitter.
So we're stuck with fields forever, and since they're there and they've taken the best syntax, it makes sense to use them when it's safe to do so.
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)
Speed. If a field gets set or read billions of times over the course of a simulation then you want to use a field and not a property to avoid the overhead och a sub routine call. Conforming to OO (DDD?) as far as possible, in these instances, I'd recommend resorting to fields only in class dedicated to representing some sort of "value" like person. Logic should be kept to a minimum. Rather, have a personcreator or a personservicer.
But if you have these issues then you're probably not programming c++ and not c#, aren't you?
There are several good (partial) answers by #Seth (fields perform better, so in a private context you might as well use that to your benefit when it makes sense), #Skurmedel (fields can be readonly), #Jenk (fields can be used for ref/out). But I'd like to add one more:
You can use the streamlined initialization syntax for setting the value of a field, but not a property. i.e.:
private int x = 7;
vs
private int x { get; set; }
// This must go in the constructor, sometimes forcing you to create
// a constructor that has no other purpose.
x = 7;
I have classes which have automatic properties only like public customerName {get; set;}. They are public because they are accessed outside the class. They can also be accessed inside the class. They offer good encapsulation and better debugging. I can put a breakpoint on one if I need to know who is accessing it and when.
My question is what are the disadvantages of using properties only with no corresponding fields? I can make the setter or getter private, internal.. etc which means I also have flexibility of scoping it when needed.
Serialization with BinaryFormatter - you have big problems if you need to change your property to a "regular" property later, for example to add some validation / eventing /etc - sinc BinaryFormatter uses the field names. And you can't duplicate this, since the field name the compiler generates cannot be written as legal C#.
Which is a good reason to look at a contract-based serializer instead. See this blog entry for more info.
You can't create truly read only property, because you have to define both setter and getter. You can only use private setter to achieve pseudo-readonly property from outside.
Otherwise, as said above there are no other disadvantages.
There are no disadvantages for simple properties. The compiler creates the backing field for you. This blog entry explains how the compiler treats automatically implemented properties.
Not really a disadvantage, but you have to be aware of the default values of automatic properties. With "classic" properties we always used to initialize the backing fields, e.g. like this:
private bool _flag = true;
public bool Flag
{
get { return _flag; }
set { _flag = value; }
}
This made it obvious what the default value of the property is.
With automatic properties, you have to know what the default values are for the different types (e.g. false for bool). If you don't want the property to have the default value you have to initialize it in the constructor:
class MyClass
{
public bool Flag { get; set; }
public MyClass()
{
Flag = true;
}
}
This means, you have to implement a constructor if you want to initialize your properties to non default values or if a property is of a reference type (class).
But as I wrote, I do not really think of this as a disadvantage, just something you have to know.
The thing is, there is a corresponding field. You just don't see it because the compiler creates it for you. Automatic properties are just syntactic sugar or shorthand way to create the field.
No major things. Just edge cases like where you need to pass a property to a method where the parameter is passed by reference (ref or out) which isn't possible with a property (because internally, they're just get_Property/set_Property methods implemented by the compiler, not special fields of some kind) and you would need an explicit private backing field for this.
EDIT: Oh, and seconding the 'no readonly' properties, which is actually fairly common.
If you don't need to perform any specific logic in the get and/or set accessors, there's no disadvantage...
I say that they are bad from a code readability standpoint. Syntax sugar is nice for writing code but horrible for reading code. As developers the code we leave behind will ultimately be inherited by some poor developer that will have to make sense out of what we did and what is going on in the code. I really am against changing a language to simply save keystrokes when there is an established syntax for the same constructs.
In Visual Studio 2008 Team System, I just ran Code Analysis (from the Analyze menu) on one of my C# projects. One of the warnings produced was the following:
Microsoft.Design : Because field 'Connection._domain' is visible outside of its declaring type, change its accessibility to private and add a property, with the same accessibility as the field has currently, to provide access to it.
It's referring to the following field:
public abstract class Connection
{
protected string _domain;
}
I don't understand the reasoning behind the suggestion. This is what I think it wants me to do:
public abstract class Connection
{
private string _domain;
protected string Domain { get { return _domain; } set { _domain = value; } }
}
Two questions:
Did I understand correctly what the suggestion wants me to do, code-wise?
Why does it want me to do this?
Yes, I think you understood correctly - although in later versions of C#, there's a more concise way to write it:
public string Domain { get; set; }
Why? It's all about encapsulation. If you do as it suggests, you can later change the definition of the Domain property without affecting any calling code that uses that property. Since your class is public, and might conceivably be called by code that you didn't write, that's potentially quite important.
This is because if you ever wanted to change the field to a property in the future you would break any other assemblies that depend on it.
It is good practice to keep all fields private and wrap them in properties so that you have the option of adding validation or other logic in the future without recompiling all consumers (or in this case inheritors) of your class.
Yep. That's the suggestion. You shouldn't have any accessibility higher than private exposed as direct instance fields.
It's one of the main principles of OOD - encapsulation also referred to as 'data-hiding'.
Yes, you did correct the problem code wise.
It is about encapsulation. _domain is data about your object. Rather then exposing it directly so that any client has unfiltered access, you should provide an interface for them to access it. Practically this might be adding validation to the setter so that it can't be set to any value. It might seem silly if you are the only one writing code because you know how your API works. But try to think about things on a large enterprise level, it is better to have an API so that your object can be seen as a box that accomiplishes a task. You might say you will never have the need to add something like validation to that object, but things are done that way to hold for the possibility of it, and also to be consistent.
Your translation is correct. The same argument for can be made for using 'protected' properties as can be made for using 'public' properties instead of exposing member variables directly.
If this just leads to a proliferation of simple getters and setters then I think the damage to code readablity outweighs the benefit of being able to change the code in the future. With the development of compiler-generated properties in C# this isn't quite so bad, just use:
protected string Domain { get; set; }
In answer to your question... yes.
However, I would just use the auto-property syntax:
public abstract class Connection
{
protected string Domain { get; set; }
}
Basically, properties provide more than returning or setting a member. They allow you to add logic that could verify a proper input format, range validation, etc.
The selected answer from the link puts it best, "Properties provide encapsulation. You can encapulate any needed validation/formating/conversion in the code for the property. This would be difficult to do for fields."
http://social.msdn.microsoft.com/Forums/en-IE/netfxbcl/thread/985f4887-92ae-4ec2-b7ae-ec8cc6eb3a42
In addition to the other answers mentioned here, public/protected members that begin with an underscore are not CLS-compliant, in that there is no requirement for .NET languages to support members with leading underscores, so someone inheriting from your class in a different .NET language may not be able to access that particular protected member.
I know, it probably doesn't apply to you, but it might be part of the reason for the code analysis warning.