Defining both Private Field and Property vs just Property - c#

Following OOP's best practices, is it better to have this code:
class Car {
private Driv driver;
public Driv Driver {
get { return driver; }
set { driver = value; }
}
}
Or this one?
class Car
{
public Driv Driver { get; set; }
}
While the second version is shorter, I feel like I'm breaking the main premise of the Encapsulation concept:
EVERY class should keep its privates to itself.
Hope the answer is not too trivial.

There really is no difference. If no private variable is created by the user then the code will be generated automatically for the private field. However, if the user wishes to do additional logic in the getter or setter of the property then declaring a private field is necessary.

Your first example is what's called a Property with a backing field
The second is called an Automatic property.
The purpose of a property with a backing field is so that you can control access to your private properties.
So... If for instance you want to, make a calculation before returning the value of your private field, you could do it in the one with the backing field.
Or lets say you have a car object with 10,000 miles on the clock... you would probably want to only increment its value using the Drive method, and hide the setter of the Property with the backing field
void Main()
{
var car = new Car();
car.Drive();
Console.WriteLine (car.Miles);
}
public class Car
{
private int miles;
public Car()
{
miles = 10000;
}
public int Miles
{
get
{
return this.miles;
}
}
public void Drive()
{
this.miles += 100;
}
}

You are not breaking encapsulation with the second approach. The second approach is syntactic sugar to make property definition less verbose. The benefit of this approach is that in the future if you need to modify the getter or the setter, you are setup to do so and will not break the API contract.

C#'s properties are simply syntactic representations of some underlying methods and variables. Essentially, the compiler turns:
public int Height { get; set; }
into:
private int height;
public int getHeight() {return height;}
public int setHeight(int h) {height = h;}
So, no you are not defying OOP encapsulation, but instead syntactically simplifying it. You could also do something like public int Height {get;} which is a nice way to create an immutable class member. It simply creates the property without a set method, so only the class itself can alter it.
Now, you only need to use properties with backing fields if you wish to do additional tasks when getting or setting a variable, such as raise an event, or update another variable. The compiler would turn:
private int height;
public int Height { get {return height;} set {height = value; OnHeightChanged();} }
into:
private int height;
public int getHeight() {return height;}
public int setHeight(int value) {height = value; OnHeightChanged();}
Hope this helps!

Related

Why is it not allowed to have only one accessor with a body instead of two?

Assume I had this property:
public int Money
{
get;
set{
Money = value;
}
}
This won't compile, saying that the get accessor must have a body because it is not marked abstract, extern or partial. If I add a body to it and return the Money property like so:
public int Money
{
get{
return Money;
}
set{
Money = value;
}
}
.. I'll have an infinite loop on my hands and my program will throw a stack overflow exception.
So my question ultimately boils down to: Is there a way I can keep the get/set accessors, return the current value in get without creating an infinite loop, and still have a body for the set accessor?
Either use:
public int Money { get; set; }
or if you really need to have a body for accessors, you need to use a backing field:
private int _money;
public int Money
{
get { return _money; }
set { _money = value; }
}
However, the latter is only used if you need to perform some additional logic (e.g. raise an event) when getter or setter is used.
Also, the latter is more or less what the compiler generates for you automatically and it can ensure that the backing field is used consistently.
If you provide only one body, it becomes hard to define how should it behave: after all you don't have access to the generated backing field in your code so the whole idea doesn't make sense.
If you declare a body for one of the accessors, you're not dealing with an auto-implemented property anymore and need to implement the other accessor as well.
This is an auto-implemented property:
public int Foo { get; set; }
Which will generate a backing field when compiled. It will represent something like this in IL:
private int BackingField_Foo;
public int Foo
{
get { return BackingField_Foo; }
set { BackingField_Foo = value; }
}
In the case of an auto-implemented property, the compiler generates the field, so it knows where to read and write the value - but you can't access it.
Now if you implement one of the accessors yourself, to write to a self-defined field yourself, it's not an auto-implemented property anymore, so you'll have to implement the other accessor as well (as long as you declare it; you can create a regular read- or write-only property just fine).
Your current code throws StackOverflowExceptions because the accessors access themselves, ad infinitum.
See also Correct use of C# properties.
You can do the one of the following:
// 1. a public variable
public int Money;
// 2. an auto-implemented, or implicit property (very much like the above)
public int Money { get; set; }
// 3. An explicit property declaration with a private variable
private int _money;
public int Money {
get {return _money;}
set {
_money = value;
// possibly do something else here
}
}

what the best way to declare a property

I'm switching from Objective-C to C# to start using the Unity engine. So I'm trying to soak in all the C# differences. Obj-C has the #synthesize that auto creates the getters and setters. To to be honest they're sort of new to me. In Obj-C I'd often do:
#synthesize myProperty = _myProperty;
Then use the _myProperty in the local class code and access that property outside of this class using myProperty. Or more accurately classInstance.myProperty.
Also in Obj-C you can declare a property to be readonly and not worry about accidentally changing it's value outside the class.
In C# I'm trying to write proper object oriented code and I struggle with this. I'm a C coder at heart and am comfortable having access to everything everywhere, which I know is bad and unnecessary. I also don't want to expose tons of properties to the GameObject Inspector. I prefer to do as much programmatically as possible.
So what is the best way to declare properties so I can access them from another class but also so they are not exposed in the Inspector? Here are some possibilities that I've encountered and used:
// 1. public static - public without being exposed in inspector
public static int myProperty;
// 2. the public _text doesn't appear in the inspector but the text one does.
public string _text;
public string text {
get { return _text; }
set {
_text = value;
}
}
// 3. private _underscore version with no setter - does removing the set make it read only?
private float _current;
public float current {
get { return _current; }
}
// 4. creating my own getter function
private int myValue;
...
int GetMyValue() {
return myValue;
}
Also.. I read somewhere that in .NET you shouldn't use underscores in property names. I don't really know what the underscore version of the property does or represents. I thought in Obj-C it effected the scope, but don't really know.
Am I even correct in calling variables properties?
Someone suggested prop tab tab which produces this:
public object MyProperty {
get;
set;
}
Unfortunately that doesn't really answer my question about read only. Is an int or string even an object? It's not in Obj-C.
Public variables (not fields) are shown in the Unity inspector. If you want a public variable to be hidden, you can preface it with NonSerialized, like this:
[System.NonSerialized]
public bool m_HideWhenInactive = false;
You can also avoid this problem entirely by making it a property. No properties are shown in the inspector:
public bool m_HideWhenInactive { get; set; }
As a fun bonus (not your question, I know), you can have a property that's world-read, private-write:
public bool m_HideWhenInactive { get; private set; }
And finally, if you DO want a variable to be serialized and stored in a prefab, but you don't want the designers editing it (if you intend to write a custom editor class), there's a different annotation for that:
[HideInInspector]
public bool m_HideWhenInactive = false;
Static fields are never shown in the inspector.
The NonSerialized and HideInspector attributes are the two options you must consider to hide members of the class from the Unity inspector. NonSerialized is not specific to Unity, HideInspector is specific to Unity. Unity looks for both of these attribute in your compiled code to determine what gets exposed in the inspector.
If you want a publicly read only property you declare it like so...
[System.NonSerialized]
private string _text;
/// <summary>
/// Gets the Text
/// </summary>
/// <remarks>May be set within this class or derived classes</remarks>
public string Text {
get { return _text; }
protected set {
_text = value;
}
}
You seem to be having issues with the meaning of access modifiers...
See this page...
https://msdn.microsoft.com/en-us/library/wxh6fsc7.aspx
Briefly...
public = accessible from anywhere, do not declare backing variables on properties as public, otherwise people can simply skip your property accessor.
protected = accessible within your class and from classes inheriting the class
internal = accessible within the same assembly
protected internal = accessible within the same assembly and from
classes inheriting the class
private = accessible only within your class
You can do away with backing variables simply by declaring
/// <summary>
/// Gets or sets the Text
/// </summary>
public string Text { get; set; }
/// <summary>
/// Gets the current
/// </summary>
public float Current { get; protected set; }
Since the advent of auto-implemented variables, there are no technical reasons for creating properties with backing variables unless you have additional logic you would like executed on the get and/or set.
e.g you wanted to create Observable entities that raise an event when a property is changed...
private int _id;
public int ID
{
get
{
return _id;
}
set
{
if (_id != value)
{
OnIDChanging(value);
ReportPropertyChanging("ID");
_id = StructuralObject.SetValidValue(value);
ReportPropertyChanged("ID");
OnIDChanged();
}
}
}
In terms of coding standards, there are plenty of them on the net. I'd recommend IDesign's...
http://www.idesign.net/downloads/getdownload/1985
You'll notice I changed the casing on the code you posted, the casing I've used adhere's to IDesign's naming guidelines
The correct way to create properties really depends on what it is you're trying to accomplish. If you're only wanting to have a property be created for further use you can create the shorthand way:
public object MyProperty { get; set; }
If more functionality is required, you can add additional functionality, such as:
private int _myInt;
public int MyInt {
get { return this._name; }
set {
if (this._name == 1) {
this._name = value;
} else {
this._name = 0;
}
}
}
The answer of your question is it simply depends on what it is you're looking to achieve and both ways are accepted.
The use of getter and setter methods, such as those found in Java, are frowned upon in C#.
To answer your other question, String is an object in C#. int is a primitive type.
Here's a quick summary of your problems.
There is a so called snippet in C# that allows you to quickly generate code. The quick shortcut for it is typing prop and then pressing tab which would generate a code to something like this.
public int MyProperty { get; set; }
Now if you're going to create fields, and you dont want to expose that to an instance. You should make it private.
Example
private int myVar; // private is not exposed on instances only public properties are
public int MyProperty
{
get { return myVar; }
set { myVar = value; }
}
Now for static fields, static fields/properties are type accessible. So to hide them, you only have to make them private
Example
private static bool myProp; // can't be accessed on the Program Type
public static bool MyProp { get; set; } // can be accessed on the Program Type
class MyClass
{
public MyClass()
{
Program.MyProp = true;
Program.myProp= true; // wont build
}
}
If you want it to be readonly and prevent modification, you can do it like this.
public int MyProperty { get; private set; } // can get but not set
private int myVar;
public int MyProperty
{
get { return myVar; } // same as the top but with a field
}
For a deeper and better understanding, please do read about What are Access Modifiers in C#?
Property patterns in the context of the Unity engine tend to differ slightly to the 'norm' of C# because of you are often interested in making them tweakable data in the editor. This means serialization.
Unity cannot serialize properties
Unity can serialize fields of primitive types and types inheriting from UnityEngine.Object are serialized references
Unity can serialize list and arrays of the types mentioned above as well
Serialized fields on MonoBehaviours are exposed in the editor and are editable
public fields are serialized by default and private fields if they are marked with the [SerializeField] attribute.
Unity also serializes fields on classes marked with [System.Serializable] if the class is a field on a MonoBehavior
For a more in-depth discussion see: https://blogs.unity3d.com/2014/06/24/serialization-in-unity/
The following pattern is common, the backing field can be set by the developer, without needing to recompile, and cannot be changed by external code at run-time.
[SerializeField]
private int editableInEditor;
public int NotEditableInEditor
{
get { return editableInEditor; }
}
So is this pattern, a lazy-getter.
private DerivedMonoBehaviour component;
public DerivedMonoBehaviour Component
{
get
{
if(component == null)
{
// Note: Using the null-coalescing operator ??
// is inadvisable when dealing with UnityEngine.Object
// references.
// See: https://blogs.unity3d.com/2014/05/16/custom-operator-should-we-keep-it/
component = GetComponent<DerivedMonoBehaviour>();
}
return component;
}
}

Are private fields needed in a class where no methods exist?

I've been using ReSharper to do some work on cleaning up a C# codebase. I had been using both private fields in model classes along with public properties. However, I'm finding that I can simply take the properties that have no backing fields and convert them into auto-properties. These are model classes; no methods exist within them to impact the data in the objects. Is it better to just use the auto-properties?
EDIT: Including example of "Backing fields"
public class Gizmo
{
//this is what I call the "backing" field, only because it's "behind" the
//publicly-accessible property and you access it through the property
private Int32 _count;
//and this is the property, of course
public Int32 Count
{
get { return _count; }
set { _count = value; }
}
}
Is it better to just use the auto-properties
If your property involve is simple get;set, you can just use a "auto-property". If I am not wrong, compiler will create a private backing field behind the scenes.
If in your property, you are doing some kind of validation before; say before set then it makes sense to use a property with a backing field (non-auto)
An example would be
private string name;
public string MyName {
get {
return name;
}
set {
name = (value == null)
? "Anonymous" : value;
}
}
Methods are irrelevant here. If you have a property of:
private int foo;
public int Foo
{
get { return foo; }
set { foo = value; }
}
Then it absolutely makes sense to turn that into:
public int Foo { get; set; }
If any other code uses the private field, you can just change it to use the property instead.
This is pretty much a code-style question. So you should have a standard for model properties throughout your project or solution. If you find that the auto properties makes your intent more obvious, by all means use them--just use them consistently.

What's the difference between a property with a private setter and a property with no setter?

If I want a read-only property, I write it like:
public int MyProperty { get { //Code goes here } }
However, the Microsoft example (and a few other examples I've seen) are written like:
public int MyProperty { get; private set; }
Is there any difference between these two, and should I start writing properties like this?
As you can see in your second sample, you can leave out the implementation for a property. .NET will then automatically create a local variable for the property and implement simple getting and setting.
public int MyProperty { get; private set; }
is actually equivalent to
private int _myProperty;
public int MyProperty {
get { return _myProperty; }
private set { _myProperty = value; }
}
Writing
public int MyProperty { get; }
does not work at all, as automatic properties need to implement a getter and a setter, while
public int MyProperty { get; private set; }
leaves you with a property that may return any int, but can only be changed within the current class.
public int MyProperty { get { ... } }
creates a read-only property.
Question is: what do you need? If you already have a member variable that's used within your class and you only want to return the current value using a property, you're perfectly fine with
public int MyProperty { get { return ...; }}
However, if you want a read-only property, which you need to set within your code (but not from other classes) without explicitly declaring a member variable, you have to go with the private set approach.
With private setter you can only assign property value inside of instance when property is without setter you can't set its value anywhere.
If you don't use an explicit member assignment in the property, you'll have to declare a private set at least in order to be able to set a value to this property. Otherwise, you'll get a warning at compile-time saying that your property cannot be assigned.
If you use an explicit member, you'll be able to assign a value to this member directly, without needing to add a private set:
private int member ;
public int MyProperty {
get { return member; }
}
// ...
member = 2;
int anotherVariable = MyProperty; // anotherVariable == 2
public int MyProperty
{
get
{
// Your own logic, like lazy loading
return _myProperty ?? (_myProperty = GetMyProperty());
}
}
A property with only a getter is very useful if you need your own logic behind the access of that property, in particular when you need the property to be lazy loaded.
public int MyProperty { get; private set; }
A property with a private setter is useful if you need the property not te be changed from the outside, but still maintained from within the class.
In both cases, you can have a backing data field for the actual value, but in the former, you'll have to maintain that yourself, and in the latter, it is maintained for you by the generated code.
There is a difference when you access the object with reflection.
public class Foo
{
public string Bar { get; private set; }
}
// .....
internal static void Main()
{
Foo foo = new Foo();
foo.GetType().GetProperty("Bar").SetValue(foo, "private?", null);
Console.WriteLine(foo.Bar);
}

What is the purpose of accessors?

Can somebody help me understand the get & set?
Why are they needed? I can just make a public variable.
Warning: I am assuming you already know about object-oriented programming.
What are properties?
Properties are language elements that allow you to avoid the repetitive getXYZ() accessors and setXYZ() mutators techniques found in other languages, like Java.
Why do they exist?
They aim to solve the following problems:
Saying get and set in the beginning of every access or mutation of a value is annoying and distracting.
In Java, you often say:
class person
{
private int _age;
public void setAge(int value) { /*check value first, then set _age*/ }
public int getAge() { return this._age; }
}
and then consistently say:
if (person.getAge() > blah || person.getAge() < 10)
{
person.setAge(5);
}
After a while, the get and set become rather annoying.
Providing direct access to the actual variable breaks encapsulation, so that's not an option.
How are they used?
They are used just like variables. You read/write to them just like variables.
How are they created?
They are created as methods. You define a pair of methods that:
Return the current value of the property. Oftentimes, this is nothing more than something like the following:
class Person
{
private int _age; //Declare the backing field
public int Age
{
get { return this._age; }
set { ... }
}
}
Set the value of the property:
class Person
{
public int Age
{
get { ... }
set
{
if (value < 0) //'value' is what the user provided
{ throw new ArgumentOutOfRangeException(); } //Check validity
this._age = value;
}
}
}
Other notes:
Auto-implemented Properties
C# 3.0 introduced auto-implemented properties:
public int Age { get; set; }
This is equivalent to:
private int _age; //The name is auto-generated
public int Age { get { return this._age; } set { this._age = value; } }
Why does it exist?
It helps you avoiding breaking changes in client executables.
Let's say you're lazy and don't want to type the whole thing, and decide to expose a variable publicly. You then create an executable that reads from or writes to that field. Then you change your mind and decide that you in fact needed a property, so you change it to one.
What happens?
The depending executable breaks, because the code is no longer valid.
Auto-implemented properties help you avoid that, without extra redundancy in your initial code.
Indexers
Indexers extend the property syntax to let you index objects (surprise!), just like arrays.
For C++ users: This is similar to overloading operator [].
Example:
private int[] _elements;
public int this[int index] //Indexed property
{
get { return this._elements[index]; }
set
{
//Do any checks on the index and value
this._elements[index] = value;
}
}
You then use them like obj[5] = 10;, which is equivalent to calling the set method of obj's indexer.
In fact, System.Collections.Generic.List<T> is indexed:
var list = new List<int>();
list.Add(10);
list[0] = 5; //You're indexing list, as though it were an array!
Isn't that neat? :)
Anything else?
There are many more features to properties, not all of which are available in C#:
Parametrized properties, of which indexers are a special kind
Getter/setter access modifiers (in C#)
Multiple getters or setters (not in C#)
Et cetera
They are called Accessors
The accessor of a property contains the executable statements associated with getting (reading or computing) or setting (writing) the property. The accessor declarations can contain a get accessor, a set accessor, or both.
The body of the get accessor resembles that of a method. It must return a value of the property type.
http://msdn.microsoft.com/en-us/library/w86s7x04.aspx
private string m_Name; // the name field
public string Name // the Name property
{
get
{
return m_Name;
}
}
The set accessor resembles a method whose return type is void. It uses an implicit parameter called value, whose type is the type of the property.
private m_Name;
public string Name {
get {
return m_Name;
}
set {
m_Name = value;
}
}
Then in the incarnation of C# 3, you can do this much easier through auto-properties
public string Name {get; set; } // read and write
public string Name {get; } // read only
public string Name { get; private set; } //read and parent write
http://msdn.microsoft.com/en-us/library/bb384054.aspx
Properties act as accessors to the internal state of an object, hiding the implementation of that state.
So, for example, you may have a first name property in a class
public class Example
{
private string firstName;
public string FirstName
{
get {return this.firstName;}
}
}
So anyone using the class doesn't need to know how first name is stored, they just know they can get a string representation of it. By adding a set you also add a mutator, something which changes an objects internal state
public class Example
{
private string firstName;
public string FirstName
{
get {return this.firstName;}
set {set this.firstName = value;}
}
}
Again you're still isolating how the first name is stored internally (encapsulation), but users can change it by passing in a string.
Simply put, get and set accessors are the functions called on a Property; that is, when you retrieve the value or when you set it. It forces a type of behavior on the way values are retrieved or set.
For example, you may want to have a mechanism to get/set passwords. Generally speaking, you'll only want to compare the hash of a password instead of storing things plaintext, so you'd have the getter variable retrieve the stored hash, and the setter would take the provided input and hash it for storage.
Here's what I mean:
public class User {
//Usery properties here, and...
private string _password;
public string Password {
get {
return _password;
}
set {
_password = SomeHashingFunction(value);
}
}
}
value is the variable provided to the setter from what has been given in the variable assignment. e.g.: someuser.Password = "blah";
Get and set are used in properties. They can each be public, protected, or private. Similar to accessor and mutator methods, they allow some computation when code tries to access/mutate the property. Of course, as long as you define one of get/set, the other is optional.
Example without properties:
private int test;
public int getTest() {
// some computation on test here, maybe?
return test;
}
private void setTest(int test) {
// some error/range checking, maybe?
this.test = test;
}
With properties:
private int test;
public int Test {
get {
// some computation on test here, maybe?
return test;
}
private set {
// some error/range checking, maybe?
test = value; // value is a keyword here
}
}
get{} and set{} are accessors that offer up the ability to easily read and write to private fields. Working with a simple example:
public class Foo()
{
//Field
private int _bar;
//Property
public int Bar
{
get { return _bar; }
set { _bar = value; }
//value is an implicit parameter to the set acccessor.
//When you perform an assignment to the property, the value you
//assign is the value in "value"
}
}
In this case, Bar is a public property that has a getter and a setter that allows access to the private field _bar that would otherwise be inaccessible beyond class Foo.
Now in a class that has an instace of Foo, you can do this:
public class IHasAFoo()
{
private Foo _myFoo = new Foo();
public void SomeMethod()
{
_myFoo.Bar = 42;
}
}
So the public accessor allows you to set the value of the private field back in Foo.
Hope that helps!

Categories

Resources