C# beginner has a problem with class attributes - c#

I am a C# beginner and and I've been working on object-orientation for the past few days.
That is why please excuse my if the question is dumb.
I wrote 2 attributes for a class. Can anyone say to me where is the difference between the first and the second?
public class house
{
private int Height;
public int _Height
{
get { return Height; }
}
public int height { get; }
}
Is there a difference between?

C# knows fields and properties. A field stores data, a property accesses it. In the basic form, this looks as follows:
public class House
{
private int _height; // a field storing an integer
public int Height // A property that can be used to access the _height field
{
get
{
return _height;
}
set
{
_height = value;
}
}
}
The above is, for an outside viewer (almost) equivalent to:
public class House
{
public int Height; // a public field storing an integer
}
but this is discouraged, because fields should not be public. If you want to change something inside your class later, that gets more difficult.
The property has different advantages, one of them being that you can debug when the value gets changed, or you can verify that the value is in range (e.g that no one is setting a negative height). You can also leave away the setter, which allows the users of the class to only read the field, but not set it.
Since properties are so common in C#, the following abbreviation is allowed:
public class House
{
public int Height // An auto-implemented property
{
get;
set;
}
}
These properties are called auto-implemented. Again, for an outsider, this looks exactly the same and the compiler actually converts this to exactly the same code as the first example above. The only difference is that you cannot directly access the field. And you cannot add verification code with this syntax.
So basically, the three variants achieve almost the same result and it is mostly a matter of taste which one to use. By convention, the last variant is mostly used if no verification needs to be done, otherwise variant 1.
Per comment, here is an example with verification:
public class House
{
private int _height; // a field storing an integer
public int Height // A property that can be used to access the _height field
{
get
{
return _height;
}
set
{
if (value < 0)
{
throw new InvalidOperationException("The height of a house cannot be less than 0");
}
_height = value;
}
}
}

Related

How to add a property to represent a sample name that may not be changed once initialized?

I am trying to make a property in my class. What would I need to do where once the property is initialized, it cannot be changed?
These are the actual instructions:
Create a class in the existing namespace, either in an existing code
file or in a new file, to represent the amount in pounds of dirt
sample. In this class (a) do not create constructors. (b) inherit the
sand class (to make use of the sand property). (c) add a property to
represent the sample name. This property may not be changed once
initialized. (d) add a property to represent and process assignments
the quantity of clay, with a minimum value of 0. (e) add methods to
return the weight of the sample, the percentage of sand in the sample
and the percentage of clay in the sample.
I am on part (c). I have tried to exclude setters. Then, I've tried to use readonly, but it cannot work because my class cannot have constructors.
public class AmountSand //parent class
{
public class AmountSand {
private double quantity;
public double Sand {
get {
return quantity;
}
set {
if (value >= 0) quantity = value;
}
}
}
public class AmountDirt: AmountSand { //part (b): inherited the parent class, AmountSand
private string name = null;
private double clay;
public string Name { //here is where the specific property starts
get {
return name;
}
set {
if (name == null)
name = value;
}
} //ends
public double Clay {
get {
return clay;
}
set {
if (value >= 0) clay = value;
}
}
Depends on from where you would like it to be initialized.
EDIT: sorry, i didn't read that your class could have ctors, but i'll keep this in for completeness. It seems kinda weird that your class can't have ctors. May I ask why?
From the ctor:
class MyClass
{
public MyClass()
{
Name = "Muhammed";
}
public MyClass(string newName)
{
Name = newName;
}
public string Name{get;}
}
If you'd like it to be initialized from outside the class, your code is not too far off. You could even remove the backing property. I'd use
if(string.IsNullOrEmpty(Name))
rather than comparing to null.
if you'd like it to be set from a method inside your class:
public string Name{get; private set;}
Strings are already immutable by nature, so you need to clarify what you're trying to accomplish.
However, if you simply don't want anything else to be able to set the value other than the class itself, then you can make the set accessor private.

How get set property works in C#?

I am new to C# and am exploring the very basic of C# get and set properties. What I have found is, The get set accessor or modifier mostly used for storing and retrieving value from the private field.
In this case, What is the problem with using public fields?
Another thing, I have written some conditions inside get and set. The code is
public int Number
{
get
{
if(Number>10)return 10;
else
{
return Number;
}
}
set
{
if (value > 10)
{
Number = 10;
}
else
{
Number = value;
}
}
}
Whats the problem here?
And another interesting thing is, in VS, the recursive sign appears where I check the conditions.Can someone explain it, please?
I am new to C# and wants to learn from the basic.
Thanks in advance.
Initial Problem - StackOverflow
The problem is that you are inadvertently using recursion, which is going to lead to a stack overflow, because your getters and setters for the Number property are getting and setting the Number property, rather than a backing field.
It should at the very least be changed to this:
private int number;
public int Number
{
get
{
if(this.number>10)return 10;
else
{
return this.number;
}
}
set
{
if (value > 10)
{
this.number = 10;
}
else
{
this.number = value;
}
}
}
You are missing a private backing field. Your property is self-referencing (hence the recursion symbol).
Try this instead:
private int _number;
public int Number
{
get
{
if(_number > 10)
{
return 10;
}
else
{
return _number;
}
}
set
{
if (value > 10)
{
_number = 10;
}
else
{
_number = value;
}
}
}
As far as I can tell you are calling the Number several times inside your code.
And the recursive loop will run forever until it runs into a StackOverflow :)
I ran your code with :
this.Number = 100;
int num = this.Number;
Basically this should trigger the setter and the getter. When the if clause is setting the number to 10, the first recursion is entered since you are setting the number again. It will try to set the number to 10 recursively by Number=10
Add a backing field above number, like this:
private int number; // Backing field
public int Number
{
get { return number; } // Getter
set { number = value; } // Setter
}
The main idea of a property with public read/write access is to simply be a mutator and accessor for the internal state of their containing object.
When you have conditional logic inside these get/set methods their "contract" with consumers of the class is being broken....when I call the accessor/getter
var number = anInstance.Number;
...I expect to receive the current state of the anInstance object's number, not some logic-driven derivative of it. Similarly for the Mutator/setter
anInstance.Number = 123;
...I expect that to automatically set the internal state of the anInstance object's number.
If i set the Number in one statement...
anInstance.Number = 123; // I expect anInstance to have an internal state of 123 for it's Number
var x = anInstance.Number; // I expect 123 back, not 10
...if I then retrieve that value on the next line, I expect the same value back, but with your current implementation (if it wasn't also recursive - see below), when I set Number to 123, this is being ignored and the value of 10 is saved as the new internal state and when I then retrieve Number I would get back a value of 10.
It is not the concern of the Number property to be changing what the caller has requested be set as it's value. An invoker of the Number property rightly expects it's instructions to be followed and the invoker shouldn't have to know about weird internal getter-setter logic in order to function.
If you really need to get/set things in a conditional way, the place for the conditional logic is outside the class containing the Number property, i.e. replace the Number property with a simple auto-implement getter-setter and use in the following way.
int x = anInstance.Number > 10 ? 10 : anInstance.Number; // replaced getter logic outside the class containing the `Number` property
anInstance.Number = x > 10 ? 10 : x; // replaced setter logic
As for the reason why you are seeing the recursion symbol, that is because your code is recursively calling itself. The Number property is calling itself, instead of some backing field. Change the property to be like...
private int number;
public int Number
{
get
{
return number; // note the lower-case 'n' refers to the private field instead of the property
}
set
{
number = value;
}
}
Note, though, that there is no need to have a private backing field when you use your property in this simple way. If the intent is to have full read-write access, you could simply use a public field.
public int Number;
However, a property allows you to control access to fields, e.g.
public int Number { get; private set; }
which a simple public property does not allow, although you can use the readonly modifier to give this behaviour.
public readonly int Number;
However, another advantage of using a property over using a field is that it can offer greater control over how internal state is used/stored, e.g.this example is taken from MSDN
class TimePeriod
{
private double seconds;
public double Hours
{
get { return seconds / 3600; }
set { seconds = value * 3600; }
}
}
In this example, the caller of this class' Hours property is getting and setting a value of hours but under the hood the internal state of the class is storing/retrieving using seconds. This would not be possible with a public field.

Public vs Private{get, set}

I'm making a new class and I caught myself wondering:
Is there any difference between writing:
public string temp;
And writing:
private string temp;
public string temp_
{
get { return temp; }
set { temp = value; }
}
I'm guessing this is kind of a newbie question, but I didn't find an absolute answer...
In both cases it seems I can access the object outside the class.
Is the private form just a sloppy way?
Yes, the difference is that you have a property. Properties in C# are a syntax sugar over having a pair of get and set method. The compiler in fact takes the code blocks and creates two separate methods: get_PropertyName and set_PropertyName, where PropertyName is the name of your property. These methods have the exact logic you implement in the get and set blocks respectively, and the code using your property will in fact be calling these methods behind the scenes.
The advantage of this is that you have full control over the way the value is set and retrieved.
Example - imagine you want to store age:
public int Age;
Now anyone using your class can easily set the age to any value they please - 1000, -1, anything.
Now if you have a property, you can make sure that doesn't happen:
private int _age = 0;
public int Age
{
get { return _age; }
set { if ( value >= 0 && value < 120 ) _age = value; }
}
Most of the time it is beneficial to declare public fields as public properties even though you don't need any validation logic, because you might need to add one in the future and if you act proactively by creating a property in the first place, other code using your library won't need to be recompiled to work.
Properties also give you more fine-grained control over the visibility of getters and setters. You can have a public property with public getter and private setter to make sure only the class itself can change the state of the property.
public Connected { get; private set; }
In addition, there are places where you really need to have a property. One of those is using the INotifyPropertyChanged interface in the MVVM pattern for WPF, UWP and others. Data binding requires a property to be bound to (although this is not completely true if you don't need notifications, as the new {x:Bind} syntax in UWP can bind to ordinary fields).
If you use this one
public string Age;
you can set the variable to any value Age = "99999999" .
if you use this
private string Age;
public string Age_
{
get { return temp; }
set { if ( value >= 0 && value < 120 ) temp = value;
else // write some message
}
}
you can write some code inside . and make some tests Before you set or get the value of the variable
Never Declare a property's first character with lower case . The property name should be like:
private string temp;
public string Temp
{
get { return temp; }
set { temp = value; }
}
Property follow the encapsulation rules. Property is a encapsulated field of variable. we can't restrict value get and set for variable at a time but by property you can. You can also define business logic or programming construct inside property. Property is transparent with any kinds of templating or persistent context(EF).

Tackling properties in the programming

I am asking a beginner level question. Though I am working in MVC but I am really confused with a simple concept and that is "Properties". There are lot of questions that
I have already gone through but there is surely a doubt in mind and did'nt able to clear it up.
Actually c# properties used for getting and setting the value to the private fields.
Like
Public class MyClass
{
private int number;
public int Number{
get{ return this.number;}
set{ number=Value }
}
}
class Program
{
static void Main()
{
MyClass example = new MyClass();
example.Number = 5; // set { }
Console.WriteLine(example.Number); // get { }
}
}
Now , the value is assigned to property also and to the variable also. Right?
Now , here is my doubt::
When we create property in model for MVc structure, we only have
public int Number{get;set;}
If this is okay to work with then why we are creating unnecessorily one more field of private access specifier. If encapsulation is the reason for that or hiding the data then why not in model in MVC?
Actually, in the above class example can I only use
Console.WriteLine(example.number);
after declaring it public?
Then what's the use of creating property over here?
Properties can be used to a store and retrieve values from a backing field (number in your case) directly as in your first sample. But property getters and setters are ordinary blocks of code that you can use as you want. So you don't have to assign a backing field, but can derive the value of a property also from another property in a getter, e.g.
public int NumberTimesTwo
{
get
{
return Number * 2;
}
}
However, as a common scenario is to have a property retrieve and assign the value of a backing field, there is a shortcut that you can use:
public int Number { get; set; }
In this case, the compiler automatically creates a private backing field that the property retrieves in the getter and assigns in the setter, so the code is equivalent to the following, but less to type:
private int _number;
public into Number
{
get
{
return _number;
}
set
{
_number = value;
}
}
As the backing field is also private, you cannot access it from outside of the class directly.
private int myVar;
public int MyProperty
{
get { return myVar; }
set { myVar = value; }
}
You are implementing Encapsulation by using MyProperty, which is public to access myVar which is private and is accessible only in the block where defined, that is, your class and not outside it.
Btw, in what way does this QA not answer your question? Try going through this for further reference.

Is there an elegant way to set a default value for a property in c#?

I have read that there are good reasons to use properties instead of fields in c# on SO. So now I want to convert my code from using fields to using properties.
For an instance field of a class, I can set a default value. For example:
int speed = 100;
For the equivalent property, which I think is:
int Speed { get; set; }
My understanding is that the Speed property will be initialised to zero when the class is instantiated. I have been unable to find out how to set a default value to easily update my code. Is there an elegant way to provide a default value for a property?
It seems like there should be an elegant way to do this, without using a constructor, but I just can't find out how.
Best bet is to do a normal old-fashioned field-backed property, like:
private int _speed = 100;
public int Speed { get { return _speed; } set { _speed = value; } }
I think easiest way to set default value:
public sealed class Employee
{
public int Id { get; set; } = 10;
}
The design-pattern I use, which is used throughout Microsoft's Windows.Forms controls and other .NET Classes. Moreover, from my understanding, the initialization outside of the contructor allows just-in-time compiler to optimze the class code.
public class Foo {
public static const int DefaultSpeed = 100;
private int _speed = DefaultSpeed;
[DefaultValue(DefaultSpeed)]
public int Speed { get { return _speed; } set { _speed = value; } }
}
public class Foo {
public static Color DefaultForecolor { get {return SystemColors.WindowText; }}
private Color _forecolor = DefaultForecolor;
[DefaultValue(DefaultForeColor)]
public Color Forecolor { get { return _forecolor; } set { _forecolor = value; } }
}
you must set the default value for the property in the constructor. There's no other way to do it besides this for automatic properties since the fields for the automatic props are declared at compile time and replaced within getter/setter. However in explicit properties, you can initialize the field the property uses to read or write as Joe mentioned in his answer.
The constructor is the only way to set the initial value of an auto property.
CciSharp supports the DefaultValue attribute, which allows placing default values on auto properties. Whether CciSharp qualifies as an "elegant" solution, however, is a matter of opinion (it acts as a post-compiler that edits the IL in the binary).

Categories