Encapsulation : what Getter returns? - c#

In Encapsulation get is readonly where set is write only
Why my output is 11110 when not using special member function?
code:
class practice_4
{
static void Main(string[] args)
{
example ABC = new example();
// ABC.Roll_ = 11;
Console.WriteLine(ABC.Roll_ );
Console.ReadLine();
}
}
class example
{
private int roll = 11110;
public int Roll_
{
get
{
return roll ;
}
//set{
// if (value > 10)
// { roll = value; }
// else
// { Console.WriteLine("error"); }
//}
}
//public example()
//{
// roll = 110;
//}
}
Output :
11110
but when I use special member function : public example()
class practice_4
{
static void Main(string[] args)
{
example ABC = new example();
Console.WriteLine(ABC.Roll_ );
Console.ReadLine();
}
}
class example
{
private int roll = 11110;
public int Roll_
{
get
{
return roll ;
}
}
public example()
{
roll = 110;
}
}
so It display Output:
110
and discard 11110

To Answer your question "Why my output is 11110 when not using special member function?"
The special member function in your class is the Constructor of your class, which means this is the special function that initializes/constructs your object from your class definition, rule to remember here is, constructors are called after your private variables statements and also when the constructor is finished the construction is finished, which means your class's internal state(variables) are now assigned(among other things).
However if you initialize the private variables like you are in private int roll = 11110; line, this line executes before the constructor is called. but as you are overwriting the value of roll in constructor, the value of your private variable gets overwritten.

In the example class you are calling the roll variable instead of the Roll_ property. If you were to try to set Roll_ instead you would get a compile time error saying something along the lines of you cannot modify a read-only property. The purpose of encapsulation is to prevent the outside world from directly modifying the value, it's not in place to prevent the class from modifying the value.

Related

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.

Why is this C# static method not thread-safe? [duplicate]

I've seen countless posts on how variable capture pulls in variables for the creation of the closure, however they all seem to stop short of specific details and call the whole thing "compiler magic".
I'm looking for a clear-cut explanation of:
How local variables are actually captured.
The difference (if any) between capturing value types vs. reference types.
And whether there is any boxing occurring with respect to value types.
My preference would be for an answer in terms of values and pointers (closer to the heart of what happens internally), though I will accept a clear answer involving values and references as well.
Is tricky. Will come onto it in a minute.
There's no difference - in both cases, it's the variable itself which is captured.
Nope, no boxing occurs.
It's probably easiest to demonstrate how the capturing works via an example...
Here's some code using a lambda expression which captures a single variable:
using System;
class Test
{
static void Main()
{
Action action = CreateShowAndIncrementAction();
action();
action();
}
static Action CreateShowAndIncrementAction()
{
Random rng = new Random();
int counter = rng.Next(10);
Console.WriteLine("Initial value for counter: {0}", counter);
return () =>
{
Console.WriteLine(counter);
counter++;
};
}
}
Now here's what the compiler's doing for you - except that it would use "unspeakable" names which couldn't really occur in C#.
using System;
class Test
{
static void Main()
{
Action action = CreateShowAndIncrementAction();
action();
action();
}
static Action CreateShowAndIncrementAction()
{
ActionHelper helper = new ActionHelper();
Random rng = new Random();
helper.counter = rng.Next(10);
Console.WriteLine("Initial value for counter: {0}", helper.counter);
// Converts method group to a delegate, whose target will be a
// reference to the instance of ActionHelper
return helper.DoAction;
}
class ActionHelper
{
// Just for simplicity, make it public. I don't know if the
// C# compiler really does.
public int counter;
public void DoAction()
{
Console.WriteLine(counter);
counter++;
}
}
}
If you capture variables declared in a loop, you'd end up with a new instance of ActionHelper for each iteration of the loop - so you'd effectively capture different "instances" of the variables.
It gets more complicated when you capture variables from different scopes... let me know if you really want that sort of level of detail, or you could just write some code, decompile it in Reflector and follow it through :)
Note how:
There's no boxing involved
There are no pointers involved, or any other unsafe code
EDIT: Here's an example of two delegates sharing a variable. One delegate shows the current value of counter, the other increments it:
using System;
class Program
{
static void Main(string[] args)
{
var tuple = CreateShowAndIncrementActions();
var show = tuple.Item1;
var increment = tuple.Item2;
show(); // Prints 0
show(); // Still prints 0
increment();
show(); // Now prints 1
}
static Tuple<Action, Action> CreateShowAndIncrementActions()
{
int counter = 0;
Action show = () => { Console.WriteLine(counter); };
Action increment = () => { counter++; };
return Tuple.Create(show, increment);
}
}
... and the expansion:
using System;
class Program
{
static void Main(string[] args)
{
var tuple = CreateShowAndIncrementActions();
var show = tuple.Item1;
var increment = tuple.Item2;
show(); // Prints 0
show(); // Still prints 0
increment();
show(); // Now prints 1
}
static Tuple<Action, Action> CreateShowAndIncrementActions()
{
ActionHelper helper = new ActionHelper();
helper.counter = 0;
Action show = helper.Show;
Action increment = helper.Increment;
return Tuple.Create(show, increment);
}
class ActionHelper
{
public int counter;
public void Show()
{
Console.WriteLine(counter);
}
public void Increment()
{
counter++;
}
}
}

Why does using delegates in c# give a stackoverflowexception

When I came across delegates I wrote this really simple program just to practice. when I run it there is a stackoverflowexception. so if anyone can tell me what is wrong with this piece of code please do cause I have wasted a lot of time on trying to make it work but couldn't.
Here is the code:
using System;
public delegate void click();
class test
{
public click flare;
public double length;
public double Length
{
get
{
return Length;
}
set
{
Length = value;
flare();
}
}
}
class glance
{
public glance(ref test a)
{
a.flare = blank;
}
public void blank()
{
Console.WriteLine("this is blank");
}
}
class Program
{enter code here
static void Main(String[] args)
{
test know = new test();
glance x = new glance(ref know);
know.Length = 10;
}
}
It has nothing to do with delegates. You are calling setter method inside of setter in Lenght property and that causes the exception.Use the backing field you created for your property:
public double Length
{
get
{
return length;
}
set
{
length = value;
flare();
}
}

Problem converting array of struct from C++ to C#

I want to convert this C++ code to C#:
typedef struct consoleCommand_s
{
char* cmd ;
void (*function)() ;
} consoleCommand_t ;
static consoleCommand_t commands[] =
{
{"clientlist", &CG__Clientlist},
{"say", &CG_Say},
{"nick", &CG_Nick},
{"logout", &CG_Logout}
} ;
// e.g.
static void CG_Logout(void)
{
// Logout
}
The closest i have come is this:
public class Class1
{
// public delegate int Calculate (int value1, int value2);
public delegate void fnCommand_t();
public class consoleCommand_t
{
public string strCommandName;
public fnCommand_t fnCommand;
public consoleCommand_t(string x, fnCommand_t y)
{
this.strCommandName = x;
this.fnCommand = y;
} // End Constructor
} // End Class consoleCommand_t
public static void Nick()
{
Console.WriteLine("Changing Nick");
} // End Sub
public static void Logout()
{
Console.WriteLine("Logging out");
} // End Sub
// string[] names = new string[] {"Matt", "Joanne", "Robert"};
public consoleCommand_t[] commands = new consoleCommand_t[] {
new consoleCommand_t("Nick", Nick),
new consoleCommand_t("Logout", Logout)
};
} // End Class Class1
Now I wanted to ask:
A) Why does Nick & Logout need to be static when all the rest is not ?
B) Is there no C-like way to initialize the commands array, that is, without new ?
You could do without having a class INSIDE another class and manage your default console commands in another.
public delegate void ConsoleCmd();
public class DefaultCommands
{
public static void Nick()
{
Console.WriteLine("I'm Nick!");
}
public static void LogOut()
{
Console.WriteLine("You're Fired!");
}
}
public class Console
{
private Dictionary<string, ConsoleCmd> mCommands;
public Console()
{
mCommands = new Dictionary<string, ConsoleCmd>();
mCommands.Add("Nick", DefaultCommands.Nick);
mCommands.Add("Logout", DefaultCommands.LogOut);
}
}
Accessing your commands would be as easy as:
ConsoleCmd command = mCommands["Nick"];
command();
EDIT: Failed to mention this. This is to point to the OP that there are other better methods to achieve what he wants to do. And probably doesn't answer his question but I hope will point him to the right direction in terms of his switch from functional programming language to purely object-oriented language.
Nick & Logout may be non-static:
public void Nick(){}
public void Logout(){}
public consoleCommand_t[] commands = new consoleCommand_t[] {
new consoleCommand_t("Nick", this.Nick),
new consoleCommand_t("Logout", this.Logout)
};
B) Is there no C-like way to initialize the commands array, that is, without new ?
Don't get hung up on the new keyword in C#, it's just how initialisation is written. In C#, the analagous distinction between stack allocation and heap allocation is made using struct vs class. (So you might like to make your ConsoleCommand_t a struct.)
Edit: And with a struct you can also do:
new consoleCommand_t() {strCommandName = "Nick", fnCommand = Nick}
And skip writing the consoleCommand_t constructor. That's about as close as you can get to your C-style struct initialization, I think

C# Locking, Properties & Permissions

I've been using lock on value type properties when multi-threaded access is required. Also, I've been meaning to become more diligent about applying proper access modifiers, especially in my library code that is starting to become useful in multiple projects. I've written some code and would like to request comments on the various strategies in it for properties and locking the member variables they wrap. Thanks.
using System;
public class Program
{
static void Main(string[] args)
{
SomeValueType svt = new SomeValueType();
SomeReferenceType srt = new SomeReferenceType();
PermissionsAndLocking p = new PermissionsAndLocking(5, svt, srt);
//Invalid.
//p.X = 6;
//Invalid
//p.Svt = new SomeValueType();
//Invalid
//p.Svt.X = 1;
//Valid, but changes a copy of p.Svt because Svt is a value type.
SomeValueType svt2 = p.Svt;
svt2.X = 7;
//Invalid
//p.Srt = new SomeReferenceType();
//Valid, change the member data of p.Srt.
p.Srt.X = 8;
SomeReferenceType srt2 = p.Srt;
srt2.X = 9;
Console.WriteLine("Press the any key.");
Console.Read();
}
}
public class PermissionsAndLocking
{
//_x cannot be changed outside the class.
//_x cannot be changed "at the same time" it is being accessed???
private readonly object _xLock = new object();
private int _x;
public int X
{
get
{
lock (_xLock)
{
return _x;
}
}
private set
{
lock (_xLock)
{
_x = value;
}
}
}
//_svt and its members cannot be assigned to outside the class.
//_svt cannot be changed "at the same time as" it is being accessed.
private readonly object _svtLock = new object();
private SomeValueType _svt;
public SomeValueType Svt
{
get
{
lock (_svtLock)
{
return _svt;
}
}
private set
{
lock (_svtLock)
{
_svt = value;
}
}
}
//private on set works for = but member data can still be manipulated...
//Locking isn't complete because the reference is returned and can be accessed at a later time???
private readonly object _srtLock = new object();
private SomeReferenceType _srt;
public SomeReferenceType Srt
{
get
{
lock (_srtLock)
{
return _srt;
}
}
private set
{
lock (_srtLock)
{
_srt = value;
}
}
}
public PermissionsAndLocking(int x, SomeValueType svt, SomeReferenceType srt)
{
_x = x;
_svt = svt;
_srt = srt;
}
}
public struct SomeValueType
{
public int X;
}
public class SomeReferenceType
{
public int X;
}
You need to read about multi-threading and concurrency. Locking is about protecting invariants whilst they are invalid, i.e., while an invariant is invalid, prevent concurrent access to the shared memory that the invariant is dependant upon. The first step is to understand what invariant your code routine has, and secondly, within which block of code is the invariant invalid.
For example, a property getter has no intrinsic need to be synchronized with a lock. It only reads the property value. What invariant is invalid while this read is going on ? An operation that reads the variable, increments it, and then writes the incremented value back to the property might need to be locked, but locking the individual getter and setter would be totally inadequate. The entire operataion, including the read and the write, would have to be inside the protected block.
You should always lock a static object, so you should mark _svtLock as static in order for the lock to have an effect.
_x cannot be changed outside the class. True. It must be changed via X.
If you implement lock correctly ( see 1), then _x can't be changed at the time it's accessed.

Categories

Resources