Is it recommended to set member variables of a base class to protected, so that subclasses can access these variables? Or is it more recommended to set the member variables to private and let the subclasses get or set the varible by getters and setters?
And if it is recommended to use the getters and setters method, when are protected variables used?
This is very similar to this question, about whether to access information within the same class via properties or direct access. It's probably worth reading all those answers too.
Personally, I don't like any fields to be non-private with the occasional exception of static readonly fields with immutable values (whether const or not). To me, properties just give a better degree of encapsulation. How data is stored is an implementation decision, not an API decision (unlike properties). Why should class Foo deriving from class Bar care about the implementation of class Bar?
In short, I'd always go for properties, and I don't use protected variables for anything other than throwaway test code.
With automatically implemented properties in C# 3.0, it's easier than ever before to turn fields into properties. There's precious little reason not to do it.
Classes in other assemblies can derive from your unsealed classes and can access protected fields. If you one day decide to make those fields into properties, those classes in other assemblies will need to be recompiled to work with the new version of your assembly. That's called "breaking binary compatibility", and is perhaps the one solid reason why you shouldn't ever expose fields outside of an assembly.
I have to agree with Jon.
But, I use protected variable for "top most" inheritance class sometime in some condition. Example, if you have an object that is readonly and you cannot set it back BUT that you can use it in a child class, I do not see why I should have a protected Get to have access to that variable. A simple protected variable do the same encapsulation because you cannot set this variable and you can access this variable only from the child class.
But set/get is the way to do for other situation.
This is a trade-off here. Setters and getters are somewhat slower than accessing fields directly, so if you are doing heavy maths and read/write these fields a lot in your subclasses, you should go for accessing the fields directly. But this is more like an exception.
Normally, you should mark them as private and go for getters/setters.
So my answer is: direct access for heavily used fields, getters/setters otherwise. Use common sense.
EDIT: I did some profiling and apparently even in Release mode, there can be up the 20% speed difference between fields and properties. See my test case here: http://pastebin.com/m5a4d1597
Related
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.
This question already has answers here:
What is the difference between a field and a property?
(33 answers)
Closed 8 years ago.
Edit, as per these comments:
Do you mean "Property" vs "Field"?
public String S1; vs public String S2
{ get; set; } – dana
Exactly dana, i mean the same. – Asad
Asad: you really need to try to use
some other term to describe what you
mean so that we can better understand
your question. C# does not have global
variables. The fields you can define
in C# are not global - they are
members of the class type. – dthorpe
Hi fellas,
Need your expert views over the difference between Field and Property. As in my project, I have used certain global variables which later on i changed to 'Properties' . My manager is asking what is the benefit of using Properties of variables instead of Fields.
Although I have replied him that Property provides a kind of secure/safe/indirect access to Field instead of modifying them directly if they are declared public or protected. But Please provide me with some more convincing arguments.
Thanks and Regards
#Asad:
You should get your terminology right: Fields are not Global Variables, C# does not have global variables (as a few commenters mentioned: you can simulate global variables, but you should not do that).
The main advantage is that you can attach all sorts of functionality to a property such as validation, synchronization etc. You can't do that for a class field. For example, a field can throw BCL exceptions on assignment but it can't throw an exception that make sense with logic in your problem domain.
Also imagine trying to protect a field for thread synchronization. You have to write extra code in all the places in your code where the field is accessed. To do that with a property you can simply wrap the getter and setter with a lock in one place. (But beware! The ease of using lock in property getters and setters can give you a false sense of security if you're working with mutable types. See the accepted answer in this post.)
Now, you might think that validation and synchronization are not important to you for this particular value, and they may never be for this particular instance. But by using properties instead of direct field access is making your application much more maintainable in the future. (Suppose the value of an integer field suddenly needs to come from a source different from the original implementation and it needs to be converted from a string to an int. If you use properties to wrap the field then you make the change in one place and all the client code that uses that property does not need to change at all!)
Also, for managing information shared across many classes (global) take a look at the singleton pattern. But beware! Even though it looks neat and clean you can still get into trouble with it. Though if you really need global data you should use properties contained in a singleton. If nothing else, it's a good organization strategy.
To avoid issues with singletons or "global" data take a look at dependency injection as a much better alternative.
C# syntax doesn't have a "global variable" declaration. It has properties and fields, and static properties and fields.
If by "global variable" you mean a static field or static property, that is different from a property or field in that the static field or property is not stored in the object instance data, it is stored in global memory. The value assigned to a static field or property is accessible to all instances of that class, and all instances see the same value. A static field is the closest thing C# has to the notion of "global variable" found in other programming languages.
A non-static property or field stores its data in the object instance data, so each instance of the object has its own local copy. Modifying object1.A property will not affect the value of object2.A property.
Have a look at Properties (C# Programming Guide)
A property is a member that provides a
flexible mechanism to read, write, or
compute the value of a private field.
Properties can be used as if they are
public data members, but they are
actually special methods called
accessors. This enables data to be
accessed easily and still helps
promote the safety and flexibility of
methods.
Properties enable a class to expose a
public way of getting and setting
values, while hiding implementation
or verification code.
A get property accessor is used to
return the property value, and a set
accessor is used to assign a new
value. These accessors can have
different access levels.
Properties that do not implement a
set accessor are read only.
I prefer properties because then when I use them in code I know exactly which class was used to call them (ex. class.property = value). Public class variables can become a real pain and waste of time when you are trying to figure out where they came from during debugging.
This question already has answers here:
Are there any reasons to use private properties in C#?
(19 answers)
Closed 9 years ago.
For private class variables, which one is preferred?
If you have a property like int limit, you want it to be:
int Limit {get; set;}
and use it inside the class, like so:
this.Limit
Is there a reason to use it or not use it? Maybe for performance reasons?
I wonder if this is a good practice.
For a private member, I only make it a property when getting and/or setting the value should cause something else to occur, like:
private int Limit
{
get
{
EnsureValue();
return this._limit;
}
}
Otherwise, fields are fine. If you need to increase their accessibility, it's already a big enough change that making it a property at that point isn't a huge deal.
Edit: as Scott reminds us in the comments, side effects in properties can often cause more pain than anything else. Don't violate Single Responsibility and limit property logic to consistent, logical operations on the value only that must be done at the gate - such as lazy loading (as in the example above), transforming an internal structure into a publicly-useful format, etc.
The only real benefit an auto-property has over a field when the accessibility is private is that you can set a breakpoint on accesses and updates of the variable. If that is important to your scenario then definitely use an auto-property. Otherwise, given there is no substantial advantage, I choose to go with the simplest construct which is a field.
I would say its good practice to use a property. If ever you had to expose the limit value and used a local member it will require more coding while if its a property it would only require a change of its modifier.
I think it's cleaner also.
Granted, since it's a private API, its an implementation detail - you can do whatever you want here. However, there is very little reason to not use a property, even for private classes. The properties get inlined away by the JIT, unless there is extra code in place, so there isn't really a performance impact.
The biggest reasons to prefer properties, IMO, are:
Consistency in your API - You'll want properties in publicly exposed APIs, so making them in the private API will make your programming exprience more consistent, which leads to less bugs due to better maintainability
Easier to convert private class to public
From my perspective, using properties in lieu of variables boils down to:
Pros
Can set a break point for debugging, as Jared mentioned,
Can cause side-effects, like Rex's EnsureValue(),
The get and set can have different access restrictions (public get, protected set),
Can be utilized in Property Editors,
Cons
Slower access, uses method calls.
Code bulk, harder to read (IMO).
More difficult to initialize, like requiring EnsureValue();
Not all of these apply to int Limit {get; set;} style properties.
The point of automatic properties is they are very quick at creating a public access to some field in your class. Now, they offer no benefit over exposing straight up fields to the outside world, other than one big one.
Your class' interface is how it communicates with the outside world. Using automatic properties over fields allows you to change the internals of your class down the road in case you need to make setting the value of that property do something or check authorization rules or something similar on the read.
The fact that you already have a property means you can change your implementation without breaking your public interface.
Therefore, if this is just a private field, an automatic property isn't really that useful, not only that, but you can't initialize public properties at declaration like you can with fields.
I generally follow the following principle: If it's for strictly private use, use a field as it is faster.
If you decide that it should become public, protected or internal some day, it's not difficult to refactor to a property anyway, and with tools like ReSharper, it takes about 3 seconds to do so... :)
There's nothing wrong with having private or protected properties; this is mostly useful when there is some rule or side effect associated with the underlying variable.
The reason why properties seem more natural for public variables is that in the public case, it is a way to hedge one's bet against future implementation changes, whereby the property will remain intact but the implementation details somehow move around (and/or some additional business rule will be needed).
On performance, this is typically insignificant, or indeed identical for straight-assignment properties.
I personally dislike (but often use) plain assignment properties because they just clutter the code. I wish C# would allow for "after the fact refactoring".
Properties provide some very good automatic features (like Json and Xml Serialization)
Fields do not.
Properties can also be a part of an Interface. If you decide to refactor later on... this might be something to consider too.
Properties are just syntactic sugar, C# will compile them into get_PropertyName and set_PropertyName, so performance differences are not a consideration.
If your data member need only set and get logic then properties are very good and fast solution in C#
When defining a class as internal, do you define what would usually be public fields as internal? Or do you leave them as public? I have a set of classes with public/private methods that I have decided to set as internal. Now, should I change the class' modifier to internal and let the rest of the methods/properties as they are (public/private) or switch them to (internal/private)?
I don't see a big point in changing it to internal, and if by some reason later I want to set them back to public it's going to give a lot of work to have to put them back to public again.
Any other thoughts on this?
I can't see any reason not to leave them as public, as your class won't be visible to outside assemblies anyway. The only case where I think this might matter is when using reflection over that class.
If I have a class that is internal, I leave the class members as public (or protected/private of course if that's what they were). I find that often I have classes that I hope I can keep internal that I end up having to expose eventually and switching all the appropriate members back to public is annoying.
You defnitely shouldn't change private members to internal as that would make them more accessible. There is no need to change public members to internal since nothing outside of the defining assembly will ever be able to get a reference to an internal class anyway.
I think you should give generally members the same visibility as you would if the Type were itself public.
That is, members that are part of the public API should be public, and members that are special-purpose helpers that should only be visible to "friend" classes should be internal.
This means there will be no changes to member visibility if you ever decide to make the Type public.
More importantly, it also documents your intention - anyone reading your code will be able to identify which (if any) members are intended to be internal.
We use internal keyword for members in internal classes, so that the intention is clear. However it fails if one implicitly implement internal interfaces, where the members have to be defined as public. We dont know why and see this as an accidental mistake in the language specification that we have to live with.
Dig around in Reflector for a bit and you'll see that the BCL itself is wildly inconsistent over this. You'll see many internal classes with public members and many others with internal members. Several classes even mix and match the two with no particular rhyme or reason that I'm able to discern.
There is no "right" answer here, but there are a few things you should consider whenever you need to make a decision on this:
internal members cannot implicitly implement an interface, and explicit implementations are always private. So if you want interface members to be accessible through the class instance (the Dispose method of IDisposable is a common one), they need to be public.
Type visibilities can change. You might decide down the road that an internal class has some valuable functionality that you want to make available to the outside. But if you do, then all public members become accessible by everyone. You should decide in advance if this is what you want.
On the other hand, another reason you might make an internal class public is if you decide that you need to subclass it and that the derived classes should be in a different assembly. In this case, some of your internal members should probably be protected internal instead, otherwise derived classes won't have access to members they might need.
In the end, what it all comes down to is writing code to be read and maintained by other people. The modifier internal can mean two very different things to a maintenance programmer:
That it doesn't seem useful to the outside world, but wouldn't actually be harmful either. A typical example would be a utility class that was whipped up in 5 minutes and doesn't do much validation or error checking. In this case, it's OK for someone to make it public as long as they tighten up the code a little and/or document how to use it properly. Make this assumption explicit by making the members public.
That it's actually not safe for outside consumption; it might manipulate some protected state, leave handles or transactions open, etc. In this case, you really want to make the individual methods internal to make it absolutely clear that nobody else should be using this class, ever.
Choose whichever one is appropriate for your scenario.
In OOP languages like C# or VB.NET, if I make the properties or methods in a super class protected I can't access them in my Form - they can only be accessed in my class that inherits from that super class.
To access those properties or methods I need to make them public, which defeats encapsulation, or re-write them into my class, which defeats inheritance.
What is the right way to do this?
If you have code which needs to ask an Class to perform a specific operation but the class does not present your code with a means to do that then the Class doesn't fulfill you codes requirements.
Its bit like saying I've got a Car (Automobile) that has a protected steering wheel so I can't access it. The car is no use to me.
Either make those members Public (or at least internal) and use them or ditch the class and use one that gives your consuming code the features it needs.
Perhaps what you are really looking for is an interface. The interface contains the members your code needs and you implement that interface on your class. The advantage here is that your class can determine that the members are being accessed via this Interface rather than an inheriting subclass.
"need to make them public which defeats encapsulation"
Don't conflate good design with the icky visibility rules. The visibility rules are confusing. There are really two orthogonal kinds of visibility -- subclass and client. It's not perfectly clear why we'd ever conceal anything from our subclasses. But we can, with private.
Here's what's important. Encapsulation does not mean hiding. Protected and private are not an essential part of good encapsulation. You can do good design with everything being public (that's the way Python works, for example).
The protected/private stuff is -- mostly -- about intellectual property management: are you willing to commit (in a legally binding, "see-you-in-court-if-it-doesn't-work" way) to an interface? If your software development involves lawyers, then you care about adding protect and private to the things you're not committed to.
If you don't have to cope with lawyers, consider doing encapsulation right but leave everything public.
Sorry, it's not clear what you mean by "in my Form" - what is the relationship between your Form and your two classes? If your classes are controls in the same project, and you want to access properties from the form, you should use the 'internal' keyword.
There are at least three ways you can limit who can use some particular instance method of particular class instances:
Define the method as `protected`, `internal`, or `private`. In the first case, an instance method will only be usable from within derived-class methods of the same instance; in the second case, all classes within the assembly will have access to those methods, but classes outside won't; in the third case, no outside classes, even derived ones in the same assembly, will have access, unless their code is nested within the declaring class.
Define the method as `public`, but have the classes that create instances keep them private and never expose them to the outside world. Anyone wanting to invoke an instance method on an object has to have an instance to invoke it on. If a class holds instances but never exposes direct references to them, the only instance methods that can ever be used on those instances will be those which the holding classes uses itself.
Define the method as `public`, but have a constructor which accepts a location into which one or more delegates to private methods may be stored. Code with access to those delegates will be able to call the methods referred to thereby, but other code will not (except by using Reflection in ways which I think are only usable in full-trust scenarios).
If Reflection in non-full-trust scenarios would allow unbound delegates to be bound to arbitrary object instances, one could use nested classes to reinforce #3 so that one would have to access private fields to gain illegitimate access to the private functions; that would definitely be forbidden outside full-trust scenarios.