Automatic properties - c#

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.

Related

The purpose of { get; set} [duplicate]

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.

How can I write a single constructor method to set two fields to a specific value

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.

Retain local variable across method calls

Is there a way in C# to have a method retain a variable across different calls? For example:
private void foo()
{
int j; //declare this so as it isn't destroyed with the stack frame.
int i = calculateSomeValue() + j;
j = i;
}
The normal way I would do this would be with a member variable like this:
private int j = 0;
private void foo()
{
int i = calculateSomeValue() + j;
j = i;
}
I don't like how the variable j can be accessed in all of the other methods of the class. Plus it just seems messy this way: defining a member variable when it will only be used in one method to keep track of the value of i when the method was last called.
Is this possible in a nice/clean way? Or should I just use the member variable way and forget about it?
You could use a tiny little nested class to encapsulate it, along these lines:
public class Test
{
private int foo()
{
return nested.foo();
}
private int calculateSomeValue()
{
return 42;
}
readonly Nested nested = new Nested();
private class Nested
{
private int j;
public int foo()
{
int i = calculateSomeValue() + j;
j = i;
}
}
}
The methods in the outer class will only be able to access the public members of Nested, so they can only access foo() in this example - j is inaccessible. But note that methods in Nested have access to all the private members of the outer class.
I don't think there is another way of giving the scope you ask. The fact that other methods can access j in this case being a member variable is a direct consequence of the OOP concepts your are using encapsulating the members inside the holder object.
So I would continue using the member variable and don't worry about other methods being able to access it. If for some reason you must avoid other methods accessing the variable, maybe you should consider refactoring in its own type although maybe with the example given is not justified.
Hope this helps.
There is a nasty way to do that using closures. But that means you have to define your methods as anonymous functions and have them wrapped in some global method where they are defined. Consider this more an academical exercise and definitely not a production solution. For a real life solution definitely consider a separate class.
static void Main(string[] args)
{
var j = 0;
Func<int> calculateSomeValue = () =>
{
return 41;
};
Action myFoo = () =>
{
int i = calculateSomeValue() + j;
j = i;
};
}
In C this is possible with static local variables
void foo()
{
static int j;
int i = calculateSomeValue() + j;
j = i;
}
In C# this functionality was intentionally not included.
You have a couple of options, which depends on the intended lifetime of j. If you just need it for successive calls and for some reason don't want to use a loop, you can go for a recursive approach
private void foo()
{
foo(0);
}
private void foo(int j)
{
int i = calculateSomeValue() + j;
foo(j);
}
If you want more control or a longer lifetime, the objected oriented way would be to push this functionality onto a class, which can be a normal class or private and nested in your existing class.
public class ParentClass()
{
FooClass bar = new FooClass();
private class FooClass()
{
private int j = 0;
public void foo()
{
int i = calculateSomeValue() + j;
j = i;
}
private int calculateSomeValue()
{
//
}
}
private void DoStuff()
{
bar.foo();
}
}
Also I suggest re-weighing if its worth it to protect the variable in the first place.

Access into global variable by Console.Readline() in C#

I'm trying to improve my program for Fibonacci numbers using of memoization:
public class MyGlobals
{
public long TotNum { get; set; }
public long[] MyNumbers { get; set; }
public void GetParam()
{
Console.Write("n = ");
this.TotNum = long.Parse(Console.ReadLine());
this.MyNumbers = new long[this.TotNum + 1];
// set all numbers to -1
for (int i = 0; i < this.MyNumbers.Length; i++)
{
this.MyNumbers[i] = -1;
}
}
}
class Program
{
static void Main(string[] args)
{
MyGlobals globVariable = new MyGlobals();
globVariable.GetParam();
long n = globVariable.TotNum;
Console.WriteLine("Fib ({0}) = {1}", n, Fibonacci(n));
Console.ReadKey();
}
static long Fibonacci(long n)
{
MyGlobals globVariable = new MyGlobals();
if (n <= 1)
{
return 1;
}
if (globVariable.MyNumbers[n] != -1)
{
return globVariable.MyNumbers[n];
}
else
{
globVariable.MyNumbers[n] = Fibonacci(n - 1) + Fibonacci(n - 2);
}
return globVariable.MyNumbers[n];
}
}
I'm trying to do something like feed an array by -1 in MyGlobals class for further using MyNumbers array in Fibonacci static method.
Until line where I'm starting to call recursive fibonacci method it holds MyNumbers array in memory. But in Fibonacci method, when I create new instance of MyGlobals class for calling MyNumbers array is this array empty... What I'm doing wrong. Can you anybody help me on this, please. Thank you very much in forward.
Declare globVariable as a static member of the Program class like so:
class Program
{
static MyGlobals globVariable = new MyGlobals();
static void Main(string[] args)
{
globVariable.GetParam();
long n = globVariable.TotNum;
Console.WriteLine("Fib ({0}) = {1}", n, Fibonacci(n));
Console.ReadKey();
}
static long Fibonacci(long n)
{
if (n <= 1)
{
return 1;
}
if (globVariable.MyNumbers[n] != -1)
{
return globVariable.MyNumbers[n];
}
else
{
globVariable.MyNumbers[n] = Fibonacci(n - 1) + Fibonacci(n - 2);
}
return globVariable.MyNumbers[n];
}
}
There is no such thing as global variables in C#. The problem you're having relates to instances of nonstatic classes.
You effectively have three separate units in your code:
One class that asks for input, holds this input and holds an array of result variables (MyGlobals). This is in fact way too much for a single class and should ultimately be split up.
One method that calculates Fibonacci numbers and stores them into the previous class (Fibonacci).
A Program class and Main() method which host your console application.
Now your problem is that you don't know how to access the array of inputs stored in 1 from method 2. There are various ways to solve that, each with their own cons and pros. The most obvious one is to pass a reference.
But before that, clean up your code: give classes and methods meaningful names, and extract logic into separate classes.
Here you'll remain with three classes:
public class FibonacciInput
{
public void GetParam()
{
// Your "MyGlobals" logic
}
}
Then the calculation logic:
public class FibonacciCalculator
{
public long Fibonacci(long index, long[] range)
{
// Your "Fibonacci()" logic
}
}
And the program:
class Program
{
static void Main(string[] args)
{
FibonacciInput input = new FibonacciInput();
FibonacciCalculator calculator = new FibonacciCalculator();
input.GetParam();
long n = input.TotNum;
Console.WriteLine("Fib ({0}) = {1}", n, calculator.Fibonacci(n, input.MyNumbers));
Console.ReadKey();
}
}
Now your calculator doesn't know anything about your input, and the need for "global variables" goes away.
The point is that the Fibonacci() method needs two things: the index (the Nth Fibonacci number it should calculate) and an array to work with (which you initialized on beforehand).
So by calling calculator.Fibonacci(n, input.MyNumbers), you solve all problems at once.
Well, may be it's not really answers your question but i'd refactor your code dividing it to logical parts where each part is only responsible for one thing :
UI
Global variables
Class that knows how to work with fibo sequence
Program (entry point)
Refactored code may look something among the lines of :
// Globals should be static
public static class MyGlobals
{
public static long TotNum { get; private set; }
public static long[] MyNumbers { get; private set; }
public static void SetNum(long num)
{
TotNum = num;
MyNumbers = new long[TotNum + 1];
}
}
// interacts with UI
public static class UIHelper
{
public static long GetParam()
{
Console.Write("n = ");
var number = long.Parse(Console.ReadLine());
return number;
}
}
// Knows how to calc fibo
static class Fibo
{
static long Calc(long[] nums, long n)
{
... calc fibonacci logic
}
}
class Program
{
static void Main(string[] args)
{
// now we can use them all
// first lets get value from console
var num = UIHelper.GetParam();
// set global variables with this value
MyGlobals.SetNum(num);
// output result :
Console.WriteLine("Fib ({0}) = {1}", n, Fibo.Calc(MyGlobals.MyNumbers, MyGlobals.TotalNum));
Console.ReadKey();
}
}
P.S.
Whether to send global values as parameters to Fibo.Calc() method or to access them directly from inside of it it's up to you. I vote for first option because it makes it easier to test this method by passing mock data.

C# allow public incrementation of property, but not explicit seting

What I want to do is allow the public incrementation of an integer value within my class, but not allow it to be publicly set explicitly.
I know that I can create a function like this:
void IncrementMyProperty()
but I'd like to allow the user to just do this:
MyClass.Property++;
without allowing this:
MyClass.Property = <SomeInt>;
It's merely for convenience. I'm just wondering if there is any way to do it.
Here's an example:
class MyClass
{
private int _count;
public int Count
{
get { return _count; }
private set { _count = value; }
}
public void AddOne()
{
_count++;
}
}
class Program
{
static void Main()
{
MyClass example;
for (int i = 0; i < 10; i++)
example.Count++;
}
}
Obviously this won't compile. It's just to show what I'd like to do.
Well, it's possible, but the solution is pretty ugly.
You can create a type that overloads the ++ operator, and make a property of that type where the setter does nothing. That will allow you to use the ++ operator on the property, but it's not possible to actually set the property using the property setter:
class MyValue {
public int Value { get; private set; }
public MyValue(int value) {
Value = value;
}
public static MyValue operator ++(MyValue v) {
v.Value++;
return v;
}
}
class MyClass {
private MyValue _count = new MyValue(0);
public MyValue Count {
get { return _count; }
set { }
}
}
Usage:
MyClass c = new MyClass();
c.Count++;
Console.WriteLine(c.Count.Value); // outputs 1
So... using the ++ operator in that way is not a good solution. Normally you don't have a setter that does nothing, that will only be confusing. Having a method that increases the counter is not as short as writing ++, but it won't be confusing as long as you name it so that it's clear what it does.
There's no way. MyClass.MyProperty++ literally translates to MyClass.MyProperty = MyClass.MyProperty + 1, which uses a "setter" and if you allow a "setter" accessor then you would allow, for example, MyClass.MyProperty = <any value>;
not if you increment the int property. but you could write example++ and overload the ++ operator for your class to increment Count, while removing its setter.

Categories

Resources