|
hi, im newbie in c# encapsulation,recently i just study an article on the encapsulation for hiding its field in class so that it protect the data by outside world...but im confuse...i did try some example.. .Below is my code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace EncapsulationExample
{
class Program
{
static void Main(string[] args)
{
School d = new School();
d.SetSchool("Alan");
Console.WriteLine("The School is :" + d.GetSchool());
d.SetSchool("Sing");//changing parameter will also change private //variable name as well
Console.WriteLine("The School is :" + d.GetSchool());
d.testing = "month";
Console.WriteLine("The testing is :" + d.testing);
}
}
public class School
{
private string name;
public string testing;
// Accessor.
public string GetSchool()
{
return name;
}
// Mutator.
public void SetSchool(string a)
{
name=a;
}
}
}
...here is my confusion..even the private variable name has been declared as private, but the variable can also be changed by assigning different parameter in SetSchool method...which is same as public string testing where we can change the variable of testing as well.What is the difference with using method and without method(access variable directly from public variable) ??....What does "protect the data by outside world" actually means? any explanation with coding would be much appreciated..Thanks in advance
|
|
|
|
|
First, C# has Properties that replace explicit getters and setters:
public string SchoolName
{
get { return name; }
set { name = value; }
}
and then instead of calling
d.SetSchool("Alan");
Console.WriteLine("The School is :" + d.GetSchool());
you just do
d.SchoolName = "Alan";
Console.WriteLine("The School is :" + d.SchoolName);
Second, the reason to do this is to separate the interface of the class from the implementation of the class. The interface is what is presented to other classes when they use your class, in other words the interface is what the class can do. The implementation of the class is the internal stuff that other classes don't need to know about, it's how a class does what it does. To maximize code re-usability classes shouldn't know or care about the how, all they need to know is the what.
This goes along with:
binn019 wrote: protect the data by outside world
This means that you don't allow other classes to access any stuff that they don't need to. Your School class stores the name of the school. Do other objects need to know how it stores that? No, they only need to know that it does store it. All other classes need to know is that they set the value d.SchoolName to something to change the name and use that same value to retrieve the name later. Internally it's up to School to store it however it makes sense. Right now it's a string but what if later on you want to change it? If you use proper encapsulation then you can change how School stores the name without affecting any other class, but what if you want to change the variable testing ? Then you have to go through all of the files in your code that use that variable and update them as well. This is the essence of encapsulation.
Example: The way things are right now you can change the variable name to an int without breaking anything:
public class School
{
private int name;
public string testing;
public string GetSchool()
{
return name.ToString();
}
public void SetSchool(string a)
{
if (!int.TryParse(a, out name))
{
name=0;
}
}
}
Why? who care. That's not relevant; what is relevant is that you can change name to anything you want without having to change any of the code in main because name is properly encapsulated. You cannot do the same thing with variable . If you change it to an int then you also have to change the code in main to reflect that change.
|
|
|
|
|
thank you Jimmanuel, you have clear some of my doubts on encapsulation. As we can do all our changes on School class without making any changes on other class. we can set any conditions in setters without changing the code from the main function.
|
|
|
|
|
Hello,
i am creating a software, which loads image(fingerprint) in picture box after i want to draw circles on the picturebox on the place i have clicked mouse. I created events on pictureBox1 MouseDown(for clicking) and Paint(for drawing). When i load my form and click on pictureBox1 nothing happens, no circles are drawn, BUT after i load image in pictureBox1 all the circles that should have been drawn before appear on picturebox with loaded image. If i click on picturebox after loading image nothing gets drawn and only if re-load image new circles appear. What am i doing wrong?
Thanks for answer
here is my code and screenshot:
Screenshot[^]
namespace fingerprint_test_v04
{
public partial class Form1 : Form
{
private ArrayList myPts = new ArrayList();
private Bitmap img = null;
public Form1()
{
InitializeComponent();
this.Text = "FingerprintzzzZZzzZZzzz";
}
public void MyPaintHandler(object sender, PaintEventArgs e)
{
Graphics g = e.Graphics;
}
private void openFPR2ToolStripMenuItem_Click(object sender, EventArgs e)
{
try
{
OpenFileDialog open = new OpenFileDialog();
open.Filter = "Image Files(*.jpg; *.jpeg; *.gif; *.bmp)|*.jpg; *.jpeg; *.gif; *.bmp";
if (open.ShowDialog() == DialogResult.OK)
{
pictureBox2.Image = img;
img = new Bitmap(open.FileName);
}
}
catch (Exception)
{
throw new ApplicationException("Failed loading image");
}
}
private void openToolStripMenuItem_Click(object sender, EventArgs e)
{
try
{
OpenFileDialog open = new OpenFileDialog();
open.Filter = "Image Files(*.jpg; *.jpeg; *.gif; *.bmp)|*.jpg; *.jpeg; *.gif; *.bmp";
if (open.ShowDialog() == DialogResult.OK)
{
pictureBox1.Image = img;
img = new Bitmap(open.FileName);
angle.Enabled = true;
angle_ValueChanged(null, EventArgs.Empty);
}
}
catch (Exception)
{
throw new ApplicationException("Failed loading image");
}
}
private void angle_ValueChanged(object sender, System.EventArgs e)
{
if (angle.Value > 359.9m)
{
angle.Value = 0;
return;
}
if (angle.Value < 0.0m)
{
angle.Value = 359;
return;
}
Image oldImage = pictureBox1.Image;
pictureBox1.Image = Program.RotateImage(img, (float)angle.Value);
if (oldImage != null)
{
oldImage.Dispose();
}
}
private void Form1_Load(object sender, EventArgs e)
{
pictureBox1.Paint += new PaintEventHandler(this.pictureBox1_Paint);
this.Controls.Add(pictureBox1);
}
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
Graphics g = Graphics.FromHwnd(this.Handle);
myPts.Add(new Point(e.X, e.Y));
Invalidate();
}
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
Graphics g = e.Graphics;
foreach (Point p in myPts)
g.DrawEllipse(new Pen(Color.Red, 3), p.X, p.Y, 10, 10);
}
}
}
|
|
|
|
|
Hi,
while not spot on, I suggest you read this little article[^] which will give you the basics of painting.
|
|
|
|
|
You are drawing on the pictureBox image. if no image is loaded nothing is drawn, but the point(s) where you clicked are loaded.
when you load an image the paint event gets called and draws a circle for each point in
myPts.
|
|
|
|
|
Hi,
I'm gonna create a BackgroundWorker with an anonymous method.
I've written the following code :
BackgroundWorker bgw = new BackgroundWorker();
bgw.DoWork += new DoWorkEventHandler(
() =>
{
int i = 0;
foreach (var item in query2)
{
....
....
}
}
);
But Delegate 'System.ComponentModel.DoWorkEventHandler' does not take '0' arguments and I have to pass two objects to the anonymous method : object sender, DoWorkEventArgs e
Could you please guide me, how I can do it ?
Thanks.
|
|
|
|
|
Try:
bgw.DoWork += ( s, e ) => { ... };
Nick
----------------------------------
Be excellent to each other
|
|
|
|
|
Thanks
|
|
|
|
|
Currently the way I work with data from SQL is I store in the records of a table in a list in memory.
I normally have a class with static methods, and at the begining of my program I would normally fill this list
Employees.FillEmployees();
Then anywhere in my program I can work with this Employee data, by using a set of static methods, or just call the List<employee> directly.
This employee data isn't often changed so I'm not worried about it changing while I'm working with it.
I'm just not sure that holding this data in memory is the best option. I know that it does take up a lot more memory, but then the access time is much quicker,then say doing a select query every time I needed the data.
Any thoughs on this would be appreciated.
Thanks
|
|
|
|
|
Are we talking about lots and lots of employees?
What does the Employee record hold? Anything big, like an image?
If not, then I wouldn't worry too much about the space - I'd be more concerned about what happens when the information is changed.
If space / time is a real concern, then try a half-way house. Hold info that won't change (and is small) such as name and employee ID / DB primary key in memory, and fetch the rest when you need it.
It really is going to depend on what your app is doing: If looking for an employee is always user initiated, then time is sort-of important - a second is generaly acceptable. If it is a batch run, then time is really important and it's worth using memory.
All those who believe in psycho kinesis, raise my hand.
|
|
|
|
|
The employee record doesn't hold much, about 15 fields, like Name, Surname, Id, etc.
There can be up to about 5000 or so Employee records.
The app is batch application that runs every 5min.
I guess I'm not too worried about holding the data in memory, more about how I'm holding this data.
For EG the below class is how I hold and Edit the data.
My methods always seem to be public and I don't think that this is the right way of doing it.
Enen though it works.
public class EMPLOYEE
{
public static List<Tools.DB.OL.Xtime.EMPLOYEE> listEMPLOYEE = new List<Tools.DB.OL.Xtime.EMPLOYEE>();
#region Methods
public static void FillEMPLOYEE()
{
listEMPLOYEE = GenericFactory<Tools.DB.OL.Xtime.EMPLOYEE>.FillList("SELECT * FROM EMPLOYEE");
}
public static void InsertEMPLOYEE(Tools.DB.OL.Xtime.EMPLOYEE employee)
{
GenericFactory<Tools.DB.OL.Xtime.EMPLOYEE>.Insert(ref listEMPLOYEE, employee);
}
public static void UpdateEMPLOYEE(Tools.DB.OL.Xtime.EMPLOYEE employee)
{
GenericFactory<Tools.DB.OL.Xtime.EMPLOYEE>.Update(ref listEMPLOYEE, employee);
}
public static void DeleteEMPLOYEE(Tools.DB.OL.Xtime.EMPLOYEE employee)
{
GenericFactory<Tools.DB.OL.Xtime.EMPLOYEE>.Delete(ref listEMPLOYEE, employee);
}
#endregion
#region SQL Queries
public static Tools.DB.OL.Xtime.EMPLOYEE FindEMPLOYEE(Predicate<Tools.DB.OL.Xtime.EMPLOYEE> p)
{
Tools.DB.OL.Xtime.EMPLOYEE employee = new Tools.DB.OL.Xtime.EMPLOYEE();
if (listEMPLOYEE.Exists(p))
{
employee = listEMPLOYEE.Find(p);
}
return employee;
}
#endregion
}
|
|
|
|
|
Bardy85 wrote:
Tools.DB.OL.Xtime.EMPLOYEE employee = new Tools.DB.OL.Xtime.EMPLOYEE();
if (listEMPLOYEE.Exists(p))
{
employee = listEMPLOYEE.Find(p);
}
This code is inefficient. listEMPLOYEE.Exists(p) loops through the items in the list to return the result. employee = listEMPLOYEE.Find(p); will again do a iteration on all items and leading into worst performance. You can do something like the following instead.
Tools.DB.OL.Xtime.EMPLOYEE employee = listEMPLOYEE.Find(p);
return employee;
Bardy85 wrote: There can be up to about 5000 or so Employee records.
How often do you search on this records? If it is quite frequent, your approach is inefficient. Because, list has sequential storage and searches will lead into O(n) complexity. In such cases, querying database will be efficient. If you still need to keep the items in memory, consider a much superior data structure than a normal list.
If you have a one to one mapping like, getting employee object from the employee name, use a Dictionary where name will be the key and employee instance will be the value. This will give you constant (O(1) ) complexity. Another alternative is to use a sorted list and do binary search for lookup. This will lead into logarithmic complexity and quite efficient with huge recordsets.
Best wishes,
Navaneeth
|
|
|
|
|
Bardy85 wrote: Tools.DB.OL.Xtime.EMPLOYEE employee = new Tools.DB.OL.Xtime.EMPLOYEE(); if (listEMPLOYEE.Exists(p)) { employee = listEMPLOYEE.Find(p); } return employee;
If you're going to keep it as a in memory List, then I think the best otion/performance
is to derive your class from IComparable<employee> and then use binary search.
something like:
public class Person: IComparable(Person){
private string name="";
private string ocupation="";
public string Name{
get{return name;}
set{name=value;}
}
.
.
.
public int CompareTo(Person other){
return this.name.CompareTo(other.name);
}
}
List(Person) persons = Utils.StoredProcs.PersonProcs.GetPersons();
Person p = persons[
persons.BinarySearch(new Person{Name="Some Name"})];
I actually implemented a Reporting program this way. It's blazing fast.
Faster then our "entity" server. Memory consumption is like 170MB for a hole year worth of data.
//And there are tens of milions rows of data from over 10 tables/classes.
Botom line: if your app is to be run by a well established nr of users within your "entity"/firm/enterprise/whatever then go for it.
Try using StoredProcs instead of string commands => significant speed gains.
|
|
|
|
|
I currently do implement IComparable<t>, but don't sort the list of Objects or Use BinarySearch.
I guess this would speed up things up. Only problem I see is that BinarySearch does not take a Predicate as an arguement, and I use Predicates to find a matching object.
Do you know another way arround this? For example my Employee object has quite a few fields and I don't always want to search where the whole employee object matches, only maybe ID or Lastname, thats why I like using Predicates. In your above example you can only search on Name.
I guess you can't do a binary search and then use Predicate to find that specific employee object, because of the way a binary sort works.
Anyway thanks for you comments. They have shed some light on my problems.
Thanks.
|
|
|
|
|
FWIW: I don't use predicates, but this little article[^] explains a lot about user-defined sorting of collections (you can't do smart searches such as BinarySearch unless your collection is sorted on the relevant criterium).
|
|
|
|
|
Agreed. I think then i'll have to sort the List on the field thats going to be most used. Then I can sort the list and use a binary search on that criterium. If I have to search on any other field I'll just have to use the standard search, which I think is a bubble search.
Anyway thanks.
|
|
|
|
|
Bardy85 wrote: I currently do implement IComparable, but don't sort the list of Objects or Use BinarySearch.
I guess this would speed up things up. Only problem I see is that BinarySearch does not take a Predicate as an arguement, and I use Predicates to find a matching object.
Do you know another way arround this? For example my Employee object has quite a few fields and I don't always want to search where the whole employee object matches, only maybe ID or Lastname, thats why I like using Predicates. In your above example you can only search on Name.
True. But it totally depends on what you want to do with the data. In my case there is just one table/class that needs to be sorted on different filed(s) for different reports.
One way to use Binary search no matter the field or fields is to sort the List proving a custom IComparer each time. This makes sence ONLY IF after you sort the list you do a lot of searching
using that comparer cause the Sort time is O(n) = n* log(n) while a LINQ/Predicate is O(n)=n, but if you do a lot of searching after sorting by the "ocupation" filed for example, then the extra time needed for sorting is totally worth the while. Hope you get what I tried to say.
modified on Saturday, January 16, 2010 5:40 PM
|
|
|
|
|
|
Now I read it too . But there are many places where they say SP are faster and I tend
to belive them. I'm no SQL guru but this is how I think of the process:
1) NO SP: => the SQL engine recieves a string/guery that needs to be compiled. So it compiles the
string query and then it performs the actual query
2) SP: => it directly executes the query
|
|
|
|
|
Hi All,
Its been quite a long time since I am stuck with this problem. I am writing an application in which user selects a portion of picture box and rest part (apart from selection) is filled with white color.
Now Problem is that FillRectange fill area more that what is selected. For example here is code to fill from 0,0 of image to first node of rectangular selection:
private void picItem_MouseDown(object sender, MouseEventArgs e)<br />
{<br />
if (e.Button == MouseButtons.Left)<br />
{<br />
_selecting = true;<br />
_selection = new Rectangle(new Point(e.X, e.Y), new Size());<br />
}<br />
}<br />
<br />
private void picItem_MouseUp(object sender, MouseEventArgs e)<br />
{<br />
if (e.Button == MouseButtons.Left && _selecting)<br />
{<br />
Rectangle cropRect = _selection; <br />
<br />
using (Graphics g = Graphics.FromImage(picItem.Image))<br />
{<br />
g.FillRectangle(Brushes.White, new Rectangle(0, 0, _selection.X, _selection.Y));<br />
}<br />
<br />
picItem.Refresh();<br />
_selecting = false;<br />
}<br />
}<br />
<br />
private void picItem_MouseMove(object sender, MouseEventArgs e)<br />
{<br />
if (_selecting)<br />
{<br />
_selection.Width = e.X - _selection.X;<br />
_selection.Height = e.Y - _selection.Y;<br />
<br />
picItem.Refresh();<br />
<br />
lblLocation.Text = "Height = " + _selection.Height.ToString() + ", Width = " <br />
+ _selection.Width.ToString();<br />
}<br />
}
Can anyone tell me why this is happening please?
|
|
|
|
|
Without actually running it it is difficult to tell, but:
1) When you show code fragments, enclose them in <pre></pre> blocks (use the "code block" widget) when you paste them - this preserves the formatting, and makes it easier to read.
2) Try bracketing your if clause - it would make it more readable, and may cure the problem.
if (e.Button == MouseButtons.Left && _selecting)
becomes
if ((e.Button == MouseButtons.Left) && _selecting)
All those who believe in psycho kinesis, raise my hand.
|
|
|
|
|
Ok, thanks.
Once again here is scenario:
1) A form with a picture box and image is loaded in picture with StretchImage mode.
2) For time being to solve this issue I want to fill picture box from 0,0 to point where use clicks.
But area filled is little greater then where it is clicked.
|
|
|
|
|
Oh, I see! Do you mean area filled is little greater one pixcel bigger than where it is clicked?
If so, then it is obvious: DrawRectangle paints from Point(X, Y) to Point( X', Y') inclusive
Change
using (Graphics g = Graphics.FromImage(picItem.Image))
{
g.FillRectangle(Brushes.White, new Rectangle(0, 0, _selection.X, _selection.Y));
} To
using (Graphics g = Graphics.FromImage(picItem.Image))
{
int X = _selection.X - 1;
int Y = _selection.Y - 1;
if ((X > 0) && (Y > 0))
{
g.FillRectangle(Brushes.White, new Rectangle(0, 0, X, Y));
}
}
All those who believe in psycho kinesis, raise my hand.
|
|
|
|
|
Hi.
I'm gonna insert a large mount of data in a ListView in VitualMode.
I have set the VrtualMode property to true :
listView1.VirtualMode = true;
Now,whenever I'm gonna add an item to the listview ( listView1.Items.Add(newItem); ) ,
I receive this exception :
When the ListView is in virtual mode, you cannot add items to the ListView items collection. Use the VirtualListSize property instead to change the size of the ListView items collection.
Would you please guide me, how I can resolve it ?
Thanks.
|
|
|
|
|