This question already has answers here:
What is the purpose of get : set? [closed]
(5 answers)
What is the difference between a property and a variable
(8 answers)
Closed 3 years ago.
I'm learning c#. I was wondering, why is
public class Example {
public int X { get; set}
}
used, when you could just use
public class Example {
public int X;
}
Both do the same thing (in my understanding). Both allow you to change the value of the variable. Why use get/set over just declaring the variable public?
The purpose of getters and setters is to do some calculation, processing or update when changing or accessing a property.
Declaring getters and settters as empty is the same as declaring a public field.
class Property {
private bool enabled = false;
private int numberOfEnabledReadings = 0;
public bool Enabled {
get
{
//Do some processing (in this case counting the number of accecess)
numberOfEnabledReadings++;
return enabled;
}
set
{
enabled = value;
//Update GUI
}
}
}
edit:
As I said before: "Declaring getters and settters as empty is the same as declaring a public field.".
Well, this is true in terms of functionality.
In fact they are not the same, as mentioned before DataBinding is implemented uppon Properties.
And, properties take a little overhead, try this:
class PropertyTest
{
public int field = 0;
public int Property { get; set; }
}
private void PropertyChangeTime()
{
int counter = 0;
var instance = new PropertyTest();
var watch = System.Diagnostics.Stopwatch.StartNew();
for (int i = 0; i < 100000000; i++)
{
instance.field = counter++;
}
watch.Stop();
var elapsedMsField = watch.ElapsedMilliseconds;
counter = 0;
watch.Reset();
watch.Start();
for (int i = 0; i < 100000000; i++)
{
instance.Property = counter++;
}
watch.Stop();
var elapsedMsProperty = watch.ElapsedMilliseconds;
Console.WriteLine($"field: {elapsedMsField}\nproperty: {elapsedMsProperty}");
}
In my machine:
field: 55
property: 68
take a look at the following sources
https://www.w3schools.com/cs/cs_properties.asp
https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/properties
basically properties allow you to specify how your class' objects are able to manipulate and/or access their private variables.
Related
This question already has answers here:
question about print List<T> to screen
(5 answers)
Print List of objects to Console
(3 answers)
Print list Object c#
(1 answer)
Why does every line in the .txt-file output end with 'System.int32'? C#
(3 answers)
Closed 2 years ago.
I'm trying to print out the int items inside the list but I get the following output, which is obviously not what I want to print:
YSolution.Dice
YSolution.Dice
YSolution.Dice
YSolution.Dice
YSolution.Dice
Source code:
class Dice
{
//defining variable and properties
private bool _hold = false;
private Random rnd;
public int Current { get; private set; }
public bool IsHolding
{
get { return _hold; }
set { _hold = value; }
}
public Dice()
{
Current = 0;
rnd = new Random(Guid.NewGuid().GetHashCode());
FRoll();
}
public int FRoll()
{
Current = rnd.Next(1, 7);
return Current;
}
class DiceCup
{
public List<Dice> Dices { get; } = new List<Dice>();
public DiceCup(int count)
{
for (int i = 0; i < count; i++)
{
Dices.Add(new Dice());
}
foreach (Dice aDice in Dices)
{
Console.WriteLine(aDice);
}
}
class Program
{
static void Main(string[] args)
{
DiceCup nbd = new DiceCup(count);
}
}
The method FRoll(); seem to not get called in the dice class for some reason, when a new item is added to the list.I really just want to print out the items in the List Dices but I do not get the output/result I want. Anyone who can spot the error?
Currently you're just calling ToString() on your Dice object. Since you haven't overriden ToString() this is just using the default object.ToString() implementation which returns the type name of the object (YSolution.Dice in your case).
You have a Current property on your dice that returns the value of the dice, if you call this method then that will return the value of the dice, which you can then print: change Console.WriteLine(aDice); to Console.WriteLine(aDice.Current);.
Alternatively, as others have pointed out, you can override ToString() on your Dice class to return the current value of the dice:
class Dice
{
//defining variable and properties
private bool _hold = false;
private Random rnd;
public int Current { get; private set; }
public bool IsHolding
{
get { return _hold; }
set { _hold = value; }
}
public Dice()
{
Current = 0;
rnd = new Random(Guid.NewGuid().GetHashCode());
FRoll();
}
public int FRoll()
{
Current = rnd.Next(1, 7);
return Current;
}
public override string ToString()
{
return Current.ToString();
}
}
you want to implement the ToString-method:
public string ToString()
{
return Current.ToString();
}
Besides overriding the ToString method, as mentioned in other answers, you could also collect the results from the dice and print those:
foreach (int result in Dices.Select(d => d.Current))
{
Console.WriteLine(result);
}
The Select method is defined in the System.Linq namespace.
I am learning about writing constructors and properties in c# and was asked to write a console app and class to operate a beverage machine. I wrote part of the class code but ran into an issue. One of the many blocks of code asks for a constructor method that starts the SodaCanCount at 5 bottles and sets the CustBalance field to zero. I don't know what this constructor should look like. I am specifically talking about the private sodaVandorClass(), right under the two private fields.
I wrote what I could so far and I have no errors however the SodaVendorClass does not look right.
namespace VendorClass
{
public class SodaVendorClass
{
// members
// fields
//Customer balance is $0 until the customer inserts a dollar
//All customer entries are one dollar increments and a soda costs one dollar.
private int CustBalance = 0;
//a machine holds 10 cans of soda
private int SodaCanCount = 5;
//A soda costs 1 dollar
//private int sodaCost = 1;
public int _SodaCanCount
{
get
{
return SodaCanCount;
}
}
public int _CustBalance
{
get
{
return CustBalance;
}
}
public int BuySoda(int pCustBalance, int SodaCanCount)
{
return SodaCanCount;
}
public void AcceptCash(int CustBalance)
{
CustBalance++;
}
public int GiveRefund(int pCustBalance)
{
return CustBalance;
}
}
I only want to see an example of a constructor that sets default values for my private class fields. Any help will be appreciated.
You can define a public constructor like below but probably you don't need one if you enable your properties to set values too
public SodaVendorClass()
{
this.CustBalance = 0;
this.SodaCanCount = 0;
}
You can make your properties writable too. Notice below are auto properties and in such case you don't need those private backing fields explicitly.
public int SodaCanCount
{
get; set;
}
public int CustBalance
{
get; set;
}
You can instantiate your type saying (using Object Initializer construct)
SodaVendorClass sc = new SodaVendorClass
{
SodaCanCount = 10,
CustBalance = 500,
};
A constructor for this class could look like this:
public SodaVendorClass () {
}
That would be an empty constructor that does nothing.
To set the two values you want, you can add some paramters:
public SodaVendorClass (int customerBalance, int sodaCount) {
this.CustBalance = customerBalance;
this.SodaCanCount = sodaCount;
}
To create an instance of this class with 5 soda cans and a customer balance of 0, you would call the constructor in the code like this:
var vendor = new SodaVendorClass(0, 5);
namespace VendorClass
{
public class SodaVendorClass
{
private int CustBalance;
private int SodaCanCount;
//...
public SodaVendorClass() // default constuctor
{
CustBalance = 0;
SodaCanCount = 5;
}
//...
}
}
Default constructor is called when you are creating object like this:
SodaVendorClass obj = new SodaVendorClass();
So obj._SodaCanCount is 5 and obj._CustBalance is 0
Also you can define constructor with parameters.
public SodaVendorClass(int balance, int count)
{
CustBalance = balance;
SodaCanCount = count;
}
and create call this constructor.
SodaVendorClass obj = new SodaVendorClass(0, 5);
A constructor is being used while creating a object like "Class obj=new Calss()". If you don define a constructor in your class a default constructor will be provided implicitly.User defined Constructor usually used for initializing value for class properties. Unlike function constructor does not have any return type at all not even void. All the answers are good.
public class SodaVendorClass{
private int CustBalance = 0;
//a machine holds 10 cans of soda
private int SodaCanCount = 5;
//A soda costs 1 dollar
//private int sodaCost = 1;
public int _SodaCanCount
{
get
{
return SodaCanCount;
}
}
public int _CustBalance
{
get
{
return CustBalance;
}
}
public SodaVendorClass(int cancount, int sodacost){
SodaCanCount=cancount;
sodaCost=sodacost;
}
}
//creating a object of Sodavendorclass
Sodavendorclass obj=new Sodavendorclass(0,0); //Provided value for class property
Notice that at the time of object creation, provided for Property. This is one of the way you can use constructor.
The Code prints different answer depending on debugging or not. What did i wrong?
class Program
{
static void Main(string[] args)
{
Feld feld = new Feld();
feld.Setze = 5;
Console.WriteLine(feld.Besetzt);
Console.Read();
}
}
public class Feld
{
public int figur;
public bool Besetzt { get => (figur != 0) ? true : false; }
public int Setze { set => figur = value; }
public int Nehmen { get { int cur = figur; figur = 0; return cur; } }
}
If i delet the last Property it work's but why?
To expand on the existing comments and answers: your Nehmen property has nasty side-effects:
public int Nehmen { get { int cur = figur; figur = 0; return cur; } }
every time the value is read, it resets itself to zero. This is a very bad idea - property get accessors should not have unexpected side-effects. Large parts of the tooling expect reading Nehmen to not do that, and the IDE / debugger will often try to help you understand your data by querying the properties to show you.
This means that when the debugger is trying to help you, it is actually resetting the values.
So: make Nehmen a method:
public int Nehmen()
{
int cur = figur;
figur = 0;
return cur;
}
The system expects methods to have side-effects, so does not invoke them to "help" you.
The only valid side-effects of property get accessors is to invoke lazy-loading / initialization side effects.
You must have the variable Nehmen in the Watch Window in Visual Studio... Or trying to access it in other way
I am converting VB6 codes to C# Here I have to convert array of struct into List approach in c# but not able to modify the value in the below sample code getting error as
"Cannot modify the return value of System.Collections.Generic.List<test.Program.TagFieldValue>.this[int]because it is not a variable".
What am I doing wrong.. Is there any other way to do it without converting my type to class?
using System;
using System.Collections.Generic;
namespace test
{
class Program
{
private struct TagFieldValue
{
private int _ID;
public int ID { get { return _ID; } set { _ID = value; } }
}
private List<TagFieldValue> mFieldValues = new List<TagFieldValue>();
static void Main(string[] args)
{
Program obj = new Program();
obj.test();
}
public void test()
{
for (int i = 1; i <= 10; i++)
{
TagFieldValue temp = new TagFieldValue();
temp.ID = i;
mFieldValues.Add(temp);
}
for (int i = 0; i <= 9; i++)
{
mFieldValues[i].ID = mFieldValues[i].ID + 10;
}
for (int i = 0; i <= 9; i++)
{
Console.WriteLine(mFieldValues[i].ID);
}
Console.ReadLine();
}
}
}
Structs are passed as value, not reference. mFieldValues[i].ID = mFieldValues[i].ID + 10; will modify the copy in the list, not the struct itself. To modify the value in the list you need to create new TagFieldValue
for (int i = 0; i <= 9; i++)
{
mFieldValues[i] = new TagFieldValue { ID = mFieldValues[i].ID + 10 };
}
Or change TagFieldValue to class
private class TagFieldValue
{
public int ID { get; set; }
}
Structs aren't that flexible. the inputs can't be defined either, so if you want to do this, you should use a class instead. I had a similar problem and changing it to a class did not give any problems.
I want to know that when you create an Automatic property
and invoke the set in the main() method for a random value , where is that value being stored ?as in this example :
class Program
{
static void Main(string[] args)
{
Example W = new Example();
W.Num = 10;
Console.WriteLine("{0}", W.Num);
Console.WriteLine("{0}", W.getNum());
}
}
class Example
{
private int num;
public int Num { get; set; }
public int getNum() { return num; }
}
why is the output :
100
Because you are returning num, not Num. And num was not initialized, so this value is 0.
Auto-implemented properties makes code cleaner when no additional logic is required for the getter or setter. The compiler actually generates a backing field for the auto-implemented property, but this backing field is not visible from your code.
In your example there is no connection between the num field and the Num property, so there no reason why the num should change.
This is nothing abnormal here.
When you call
Example W = new Example();
then initially num = 0 and Num = 0;
you assigned Num, not num.
num in your Example class is redundant.
If you wrote this before automatic property initialisers were added to c#, it would look like this:
private int num;
public int Num
{
get{ return num;}
set{ num = value;}
}
Writing public public int Num { get; set; } is essentially the same thing behind the scenes. There is no need to implement getNum() (like Java), since this is equivalent to int a = w.Num;.
if use new keyword , you created new instance your class And all object recreated.
For Example ;
class Program
{
static void Main(string[] args)
{
Example W = new Example();
W.Num = 10;
Example W1 = new Example();
Console.WriteLine("{0}", W.Num); //10
Console.WriteLine("{0}", W1.Num); //0
}
}
this is only information your answer ; you returning different variable. you not set them.