C# encapsulation (get and set) - c#

I am doing exercises in Head First C# book.
This code is supposed to be about encapsulation.
class DinnerParty
{
private int NumberOfPeople;
....
public void SetPartyOptions(int people, bool fancy) {
NumberOfPeople = people;
.....
}
public int GetNumberOfPeople() {
return NumberOfPeople;
}
}
In form1 class
public partial class Form1 : Form
{
DinnerParty dinnerParty;
public Form1()
{
InitializeComponent();
dinnerParty = new DinnerParty() {NumberOfPeople = 5 };
...
Is this suppose to work?
Visual Studio is showing me an error. (cannot access due to its protection level)
I am very new at this.
Thanks

That's becouse NumberOfPeople is private means that it can't be accessible from outside the class DinnerParty, so you need to make it public.

No that is not supposed to work. I can't see the book, so I can't comment on the context. However:
public int NumberOfPeopoe {get;set;}
Is a reasonable fix.

You could use the idea of a "Fluent interface" by writing something like:
class DinnerParty
{
private int NumberOfPeople;
....
public DinnerParty SetPartyOptions(int people, bool fancy) {
NumberOfPeople = people;
.....
return this; // Return own instance to allow for further accessing.
}
public int GetNumberOfPeople() {
return NumberOfPeople;
}
}
And then call it:
public partial class Form1 : Form
{
DinnerParty dinnerParty;
public Form1()
{
InitializeComponent();
dinnerParty = new DinnerParty().SetPartyOptions( 5, true );
...

NumberOfPeople is a private member and you can not use it out of the class dude

The NumberOfPeople is private, so it will not work. The best solution here is to create public property instead of private field or add constructor and initialize this field there.

You can't initialize a private field outside your scope (class).
Make it a property.
public int NumberOfPeople { get; set; }
and now, this will work
dinnerParty = new DinnerParty() { NumberOfPeople = 5 };

Related

Calling correctly a method of another class?

See fellows I have a problem and is that i think my code is in a loop
And before you answer "RePoST" I have visited all the other threads and i still did not hit with a solution
namespace Triangle_Proportions
{
public partial class Form1 : Form
{
public class Data : Form1
{
public static class Variables
{
public static int A;
public static int B;
public static int C;
public static int a;
public static int b;
public static int c;
}
public void Set_Variables()
{
Variables.A = label0A.Left;
Variables.B = label0B.Left;
Variables.C = label0C.Left;
Variables.a = label_a.Left;
Variables.b = label_b.Left;
Variables.c = label_c.Left;
}
}
public Form1()
{
InitializeComponent();
Data etc = new Data();
etc.Set_Variables();
}
}
}
This part of the code its only goal is to call Set_Variables(); after InitializeComponent();
I know I can solve this simply by just "quicking out" Variables and Set_Variables from Data but i want both to remain inside Data because is easier to look it up when searching this.
It doesn't have any syntax errors but every time I decide to call Set_Variables(); the program never opens
You have a recursion problem.
In the constructor of Form1 you instaniate a new class which is also inherited from Form1 which is calling the constructor again. See the problem?
Create a non static version:
public class Variables
{
public int A;
public int B;
}
And your Form:
public partial class Form1 : Form
{
private Variables _variables;
public Form1()
{
InitializeComponent();
_variables = new Variables
{
A = label0A.Left,
B = label0B.Left
};
}
}

Attribute to mark as "internal use"

I made a class which requires the public default constructor but
that is never called; instead another constructor is used at DataGrid.AddingNewItem.
I'd like to tell developers that the default constructor is not for their use.
Is there an attribute which suits the purpose?
I had checked DebuggerNonUserCode and MethodImplAttribute with MethodImplAttributes.InternalCall but not sure that's the proper approach.
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.dataGrid1.CanUserAddRows = true;
var list = new List<RowX>();
this.dataGrid1.ItemsSource = CollectionViewSource.GetDefaultView(list);
this.dataGrid1.AddingNewItem += (s, e) => e.NewItem = new RowX("ABC");
}
}
public class RowX
{
public RowX()
{
//this is not used. but CollectionView require this to be public or
//CanUserAddRows doesn't work.
}
public RowX(object o)
{
//this is the actual ctor.
}
public string Text { get; set; }
}
Mark it private
class Foo
{
private Foo() {}
}
You can give your constructor an access modifier.
private This means it can only be called from another constructor in that class.
public class PrivateClass
{
//Only from inside this class:
private PrivateClass()
{
}
public static PrivateClass GetPrivateClass()
{
//This calls the private constructor so you can control exactly what happens
return new PrivateClass();
}
}
internal This means only code in the same assembly (i.e. from inside your library) can access it.
public class InternalClass
{
//Only from within the same assembly
internal InternalClass(string foo)
{
}
}

Access form label from another class/namespace

I know this has been asked thousands of time but still after a lot of research I can't find a solution and I am really sorry about this post.
I want to access my Label from a class in another namespace.
This is a sample of code to understand better what I am trying to do:
public partial class Main : Form
{
public Main()
{
InitializeComponent();
}
}
//class in another namespace
class Servers
{
public void _SetlabelText()
{
Main.label1.Text = "New Text";
}
}
How am I supposed to do it the proper way?
One option is to store a reference to the form in the constructor like this:
public class Servers
{
private Form _frmMain;
public Servers(Form frmMain)
{
_frmMain = frmMain;
}
public void SetlabelText()
{
_frmMain.label1.Text = "New Text";
}
}
And use it like this:
public partial class Main : Form
{
public Main()
{
InitializeComponent();
var servers = new Servers(this);
servers.SetlabelText();
}
}
However, it's typically advised to return back to the Form class and set it there, like this:
public partial class Main : Form
{
public Main()
{
InitializeComponent();
label1.Text = Servers.GetTextForLabel();
}
}
public class Servers
{
public static string GetTextForLabel()
{
return "New Text"; //(I assume this will be much more complex)
}
}

how to use interface in C#

Using C# .NET 4.0, Visual Studio 2010.
Well at the moment I'm looking into de-coupling of Classes and using interfaces.
I've implemented a Solution from another post to test if I could get it working but unfortunately I have never used an interface ever.
So here's the basics of what I have:
Form1:
partial class Form1 : InterfacePareto
{
public string myTest
{
get { return herpTxt.Text; }
set { herpTxt.Text = value; }
}
}
Interface:
interface InterfacePareto
{
string myTest { get; set; }
}
MyWorkingOutClass:
Class MyWorkingOutClass
{
private readonly InterfacePareto pare;
public MyWorkingOutClass(InterfacePareto pare)
{
this.pare = pare;
}
private void Testtime()
{
string firstName = pare.myTest;
pare.myTest = firstName + " extra";
}
}
The purpose:
The plan at the moment is to get the text from the forms textbox. Then pass it to the working class. The working class then does whatever calculations etc needed, then passes the result back to the forms textbox.
My question is, is my code along the right tracks. If yes, then what am I missing/doing wrong? Or if anyone thinks this is not the right way of achieving what I need, do they have any suggestions?
Many thanks!
I've just tested code and this works fine for me:
public partial class MainForm :Form, InterfacePareto //My main form inheriting Form class and interface
{
public MainForm()
{
InitializeComponent();
}
public string myTest
{
get { return herpTxt.Text; }
set { herpTxt.Text = value; }
}
private void button1_Click(object sender, EventArgs e)
{
//On button click create MyWorkingOutClass instance and pass MainForms instance
MyWorkingOutClass mc = new MyWorkingOutClass(this);
//After this line text box content will change
mc.Testtime();
}
}
//Changed modifier to public
public interface InterfacePareto
{
string myTest { get; set; }
}
//Changed modifier to public
public class MyWorkingOutClass
{
private readonly InterfacePareto pare;
public MyWorkingOutClass(InterfacePareto pare)
{
this.pare = pare;
}
//Changed modifier to public
public void Testtime()
{
string firstName = pare.myTest;
pare.myTest = firstName + " extra";
}
}
This should work fine.
There is one issue you will get when the MyWorkingOutClass does its work on a different thread than the UI thread.
To solve that you might want to change the implementation on the form to switch to the UI thread.

use class in another windows form c#?

I have a problem in a same namespace:
public partial class frmForm1 : Form // Form1
{
public class Account
{
public string Username, Password, RePassword, Name, bd, dt, dc;
}
public class ListAcc
{
public static int count = 0;
private static List<Account> UserList;
public static List<Account> Data()
{
return UserList;
}
}
public partial class frmForm2 : Form // Form2
{
private void button2_Click(object sender, EventArgs e)
{
ListAcc A; // error
string n = A<Account>[0].Usename; // error
// What should i do?
}
}
Someone can help me fix this problem? Thanks a lot!
You've nested the Account and ListAcc class inside the frmForm1 class.
Move them outside of frmForm1's class definition or change it to be frmForm1.ListAcc A;
Also, I'm not sure what you're trying to do here. This wouldn't compile no matter what you do. Are you trying to make ListAcc a generic class?
string n = A<Account>[0].Usename; // error
If you need Account in more than one class maybe it's better not to put in in the frmForm1 but in a separate file. A class inside another class is not a good idea.
public partial class frmForm1 : Form // Form1
{
public class Account
{
//some code
}
public class ListAcc
{
//SomeCode
}
}
public partial class frmForm2 : Form // Form2
{
private void button2_Click(object sender, EventArgs e)
{
//Thats will work
frmForm1.ListAcc A = new frmForm1.ListAcc();
string n = A.Data()[0].Usename;
}
}
the way your class structure is defined you need to declare the variable like this
frmForm1.ListAcc A;
Move Account class outside the frmForm1 class.
Or you should address your Account type through its "parent" type frmForm1:
frmForm1.Account

Categories

Resources