namespace tutor4
{
class Class1
{
int _num = 2;
public int num
{
get
{
return _num;
}
set
{
_num = num;
}
}
public void incrementFunction()
{
num++;
Console.WriteLine("The value of _num is "+ num);
}
}
}
namespace tutor4
{
class Program
{
static void Main(string[] args)
{
Class1 class1Obj = new Class1();
for(int i=0;i<7;i++)
class1Obj.incrementFunction();
}
}
I don't know why _num does not increase, can anyone explain please?
Your setter for num property is wrong.
It should not be
set
{
_num = num;
}
because in this case it does nothing (sets _num back to its value since getter for num returns _num so this line is equivalent to _num = _num)
It should be
set
{
_num = value;
}
MSDN explanation about value keyword:
The contextual keyword value is used in the set accessor in ordinary
property declarations. It is similar to an input parameter on a
method. The word value references the value that client code is
attempting to assign to the property
Also note: your num property is just simple wrapper of _num field of class. If you don't need some complex logic in getter and setter for this property - you can change it to auto-implemented property like this:
class Class1
{
public int num { get; set;}
public Class1
{
num = 2;
}
}
Until C# version 6 you should assign default value to auto-implemented property in class constructor.
In C# version 6 (not yet released, should be available this summer) you will be able to assign default value to auto-implemented property in declaration:
public int num { get; set;} = 2;
Related
I am using a get set method to loop another method. As shown below, I am trying to increase the value of Table10_3 in the ValuesForTableLooping class. In the Main method, I have called the get set property to increase the value by one.
I have 2 questions at hand,
Is there a way to call the get set method without putting it as Inc.Val = 0;?
Why does changing any value in Inc.Val = 0; not affect the outcome?
class Class2
{
public class ValuesForTableLooping
{
public static int Table10_3 = 1;
}
public static void Main()
{
Console.WriteLine(ValuesForTableLooping.Table10_3);
Increase Inc = new Increase();
Inc.Val = 0;
Console.WriteLine(ValuesForTableLooping.Table10_3);
Inc.Val = 0;
Console.WriteLine(ValuesForTableLooping.Table10_3);
Inc.Val = 0;
Console.WriteLine(ValuesForTableLooping.Table10_3);
}
public class Increase
{
private int val;
public int Val
{
get { return val; }
set { val = ValuesForTableLooping.Table10_3++; }
}
}
}
Thank you so much once again!
Your design is pretty strange and you seem to have a great misunderstanding on what properties are.
A property is nothing - as you noticed - as a get- and a set-method. So you could achieve the exact same with the following code:
public int get_Val() { return val; }
public void set_Val(int value) { val = ValuesForTableLooping.Table10_3++; }
And here is the weird thing. A setter expects a new value for your property, which is provided as value. However you don´t use that value at all in your implementation. Instead you just increase val by one, which I would call a really strange design. You either want to set the new value from the outside with this:
public void set_Val(int value) { val = value; }
or in the property-notation:
public int Val {
get { return val; }
set { val = value; }
}
which can be further simplified by using an auto-implemented property:
public int Val { get; set; }
Another - IMHO better - way is to omit the setter completely and create some IncreaseVal-method instead:
public void IncreaseVal() { ValuesForTableLooping.Table10_3++; }
Last but not least Increase is a very bad name for a class. It does not describe a thing, but something you can do with a thing.
I have been taught in school about C#. We did some basic stuff like loops, if etc.
Now we do more about OOP. Teacher said us something about auto-implemented-property and I find this feature as great. But I am curious how can I set value of property via method.
When we didn't know auto-implemented-property. We always did a method to set or get value of class.
But when I use auto-implemented-property I do not see any methods to get or set value of class instance. So how can I set the value of some property of class when I can set the value only via constructor. I want to know that, because when property is private I can set it only via constructor, which is not a problem, but what I can do when I want to set value via Console.Readline(); ?
namespace _001_dedicnost
{
class Car
{
int Size { get; set; }
}
class Program
{
static void Main(string[] args)
{
Car car1 = new Car(5);
// but the following line wont work
car1.Set(51);
}
}
}
Your class Car have PRIVATE property Size, so u cant't have access to it from your code, only from class CAR
If u want to set value to this property, u have to declare it PUBLIC:
class Car
{
public int Size { get; set; }
}
static void Main(string[] args)
{
Car car1 = new Car();
car1.Size = 1;
}
When you put the property on the left-hand side of an expression, the set method is automatically called on it with the right-hand side of the expression as the value.
So car1.Size = 51 is like calling the expanded setter for the Size property with value being 51.
This
public class Point {
public int X { get; set; } = 0;
}
is equivalent to the following declaration:
public class Point {
private int __x = 0;
public int X { get { return __x; } set { __x = value; } }
}
This means you have "couple of 'methods' under c sharp compilator which called using '=' sign"
Point p = new Point();
p.X = 10; //c# compiler would call something like p.__set_X(10)
int i = p.X; //c# compiler would call something like int i = p.__get_X();
Read more about auto-properties https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/classes#automatically-implemented-properties
Btw I dont recommend to use it - it breaks readability and refactobility of code ;(
If the class is a simple anemic model (without logic), set the property as public, and it will work.
If you want to control the invariants (business rules), you'd want to have a public Size { get; private set; } with a public void SetSize(int size) { /* ... */ } which contains your business rules.
Here are three 'patterns' normally used in C#:
// Anemic domain model (simple entity)
public class Car
{
public int Size { get; set;}
}
// Domain model with business rules
public class Car
{
public int Size { get; private set; }
public void SetSize (int size)
{
// check to make sure size is within constraints
if (size < 0 || size > 100)
throw new ArgumentException(nameof(size));
Size = size;
}
}
// Value object
public class Car
{
public Car (int size)
{
// check constraints of size
Size = size;
}
public int Size { get; }
}
This question already has answers here:
Overloading getter and setter causes a stack overflow in C# [duplicate]
(4 answers)
Closed 3 years ago.
class Program
{
static void Main(string[] args)
{
something s = new something();
s.DoIt(10);
Console.Write(s.testCount);
}
}
class something
{
public int testCount
{
get { return testCount; }
set { testCount = value + 13; }
}
public void DoIt(int val)
{
testCount = val;
}
}
Is what I have, because I was wanting to test and play around with the getters/setters stuff for C#. However, I get a StackOverFlowException was unhandled at "set { testCount = value + 13}". And I can't step through it, as I get a "The debugger cannot continue running the process. Process was terminated" message from Visual Studio. Any ideas what I'm doing wrong?
Edit: Today I've learned that I've done a pretty stupid derp. Given the multitudes of instant responses. Now I know better.
You have an infinite recursion, as you are referring to the property in the property.
You should use a backing field for this:
private int testCount;
public int TestCount
{
get { return testCount; }
set { testCount = value + 13; }
}
Note the property name TestCount (which also conforms to C# naming standard), as opposed to the field name testCount (lowercase t).
You should declare a variable to back the property:
class something
{
private int _testCount;
public int testCount
{
get { return _testCount; }
set { _testCount = value + 13; }
}
...
You have a circular reference in your property's getter. Try this:
class Something
{
private int _testCount;
public int TestCount
{
get { return _testCount; }
set { _testCount = value; }
}
public void DoIt(int val)
{
_testCount = val;
}
}
This:
public int testCount
{
get { return testCount; }
it returns itself, which causes it to execute itself.
Instead of return the own property in itself, store the intended value in another (preferably protected or private) variable. Then manipulate that variable both in the setter and in the getter.
class Program
{
static void Main(string[] args)
{
something s = new something();
s.DoIt(10);
Console.Write(s.testCount);
}
}
class something
{
private int _testCount;
public int testCount
{
// you are calling the property within the property which would be why you have a stack overflow.
get { return _testCount; }
set { _testCount = value + 13; }
}
public void DoIt(int val)
{
testCount = val;
}
}
What is value keyword here and how is it assigning the value to _num? I'm pretty confused, please give the description for the following code.
private int _num;
public int num
{
get
{
return _num;
}
set
{
_num=value;
}
}
public void button1_click(object sender,EventArgs e)
{
num = numericupdown.Value;
}
In the context of a property setter, the value keyword represents the value being assigned to the property. It's actually an implicit parameter of the set accessor, as if it was declared like this:
private int _num
public int num
{
get
{
return _num;
}
set(int value)
{
_num=value;
}
}
Property accessors are actually methods equivalent to those:
public int get_num()
{
return _num;
}
public void set_num(int value)
{
_num = value;
}
The value keyword is a contextual keyword, that is, it has a different meaning based on its context.
Inside a set block, it simply means the value that the programmer has set it to. For instance,
className.num = 5;
In this case, value would be equal to 5 inside of the set block. So you could write:
set
{
int temp = value; //temp = 5
if (temp == 5) //true
{
//do stuff
}
_num = value;
}
Outside of a set block, you can use value as a variable identifier, as such:
int value = 5;
Note that you cannot do this inside a set block.
Side note: You should capitalize the property num to Num; this is a common convention that makes it easier for someone who's reading your class to identify public and private properties.
Properties are the way you can READ, WRITE or COMPUTE values of a private field or class variable.
The set or setter inside a property is used when the code assigns a value into the private field or (class) variable.
The value keyword means simply "the thing that is being assigned".
public class StaffMember
{
private int ageValue;
public int Age
{
set
{
if ( (value > 0) && (value < 120) )
{ this.ageValue = value; }
}
get {
return this.ageValue;
}
}
}
//Rob Miles - C# Programming Yellow Book
Do these statements mean the same thing?
int x { get; }
readonly int x;
In answer to your question: There is a difference between readonly and {get; }:
In int x { get; } (which won't compile as there's no way to set x - I think you needed public int x { get; private set; } ) your code can keep changing x
In readonly int x;, x is initialised either in a constructor or inline and then can never change.
readonly int x; declares a readonly field on a class. This field can only be assigned in a constructor and it's value can't change for the lifetime of the class.
int x { get; } declares a readonly auto-implemented property and is, in this form, invalid (because you'd have no way whatsoever to set the value). A normal readonly property does not guarantee to return the same value every time it is called. The value can change throughout the lifetime of the class. For example:
public int RandomNumber
{
get { return new Random().Next(100); }
}
This will return a different number everytime you call it. (Yes, this is a terrible abuse of properties).
No, the statements do not mean the same thing. The full version of the property will have a backing variable:
private int _x;
public int X
{
get { return _x; }
}
Another method in the class could modify the backing variable, changing the value of the property:
private void SomeMethod(int someValue)
{
_x = someValue * 5;
}
The readonly keyword only allows a member variable to be assigned in its declaration or in the constructor:
// Both of these compile
private readonly int _x = 1;
public SomeClass()
{
_x = 5;
}
// This will not compile
private void SomeMethod(int someValue)
{
_x = someValue * 5;
}
So a get-only property whose backing variable is marked readonly is a true read-only property.
Other answers are sorta outdated…
In newer versions of C# you can assign a default value to int x { get; } = 33; which changes things.
Basically, it gets compiled down to get-only property with a readonly private backing field. (See https://softwareengineering.stackexchange.com/q/372462/81745 for more details)
Another difference I see is that you can't use the readonly version when using interfaces as you can only define methods and properties.
readonly keyword is making sure that these variables dont change once initialised // it is equalant to making a variable private and setting getter for it.
Example.
public class PlayerAuthData
{
public readonly string emailId, password, userName;
private string hello;
public PlayerAuthData(string emailId, string password, string userName)
{
this.emailId = emailId;
this.password = password;
this.userName = userName;
}
public string Hello
{
get { return hello; }
set { hello = value; }
}
}
public class AuthManager
{
void Start()
{
PlayerAuthData pad = new PlayerAuthData("a#a.com", "123123", "Mr.A");
pad.Hello = "Hi there";
print(pad.Hello);
print(pad.password);
print(pad.emailId);
print(pad.userName);
}
}
Literally, there's no big difference because you've declared x to be private (the default). You can always re-compile your class to make x different.
However, if it were public, the definition public int x { get; } allows you to later expand the definition to something like this:
int x { get {
return DoSomeOperation();
}
}
You can do that without breaking your clients. The implementation of the getter is private and clients call it without knowing if it is a static value or has an operation inside its get accessor.
Propery can have backing variable that can be set using any method of that class
private int a;
public int A{get;}
public void ChangeAMethod(int value){
a=value;
}
However readonly fields can only be assigend in constructor or in-line.