stackoverflowexception solution in C# - c#

How can I prevent this exception to happen as I have to attain some values from one class and pass it to another class where as it's object is already in that class??
My first class is:
public partial class Rack : UserControl
{
ContainerAdmin a = new ContainerAdmin();
public Rack()
{
InitializeComponent();
}
public string getposition()
{
PositionLabel.Text = Regex.Replace(PositionLabel.Text, "[^0-9]+", string.Empty);
return PositionLabel.Text;
}
}
And my other class is :
public partial class ContainerAdmin : UserControl, IDataConsumer<ContainerAdminAssemblyAdapter>
{
public ContainerAdminAssemblyAdapter Adapter { get; set; }
Rack[] racking = new Rack[64];
}
A recursive loop will occur so I want to prevent this.

You have a situation where creating a ContainerAdmin creates an array of Racks which then creates a ContainerAdmin which then creates an array of Racks and so on. It's like a function calling itself without a stop condition and that's why you're getting the stack overflow.
To solve this problem, you have to restructure your program. In either the ContainerAdmin or Rack class, you shouldn't be creating new instances of the other. Using my psychic powers, I'd guess that the Rack objects should be provided with a preexisting ContainerAdmin object.

You are in a circular loop here. In other words you have created circular dependency here. That is why you are getting this exception.
Rack is creating instance of ContainerAdmin and ContainerAdmin is
creating instance of Rack.

Related

Check from which Class the object has been created

I was searching for a common question but couldn't find any solution even after googling. Maybe I am searching wrong?
Is it possible to know from which class the object has been created?
For Example: In Visual Basic Code:
I have a class,
Public Class dummyA
End Class
I have another class,
Public Class dummyMain
Dim dmmA As New dummyA
End Class
Can I check in dummyA, if the object has been created from dummyMain?
Answer with c# or VB.Net would be great. Thanks.
Easiest way is to have an overloaded constructor and pass the owner into it.
public class DummyA
{
public DummyA(object owner)
{
var createdByDummyMain = owner is DummyMain;
}
}
and then do
public class DummyMain
{
public DummyMain()
{
var dmmA = new DummyA(this);
}
}
There is also this but it won't give you exactly what you want. There are other proposals too that deal with StackFrame but it isn't reliable due to JIT optimizations.

c# Calling method in partial call from another class

I'm making c# app where I need to access method in partial class from another class.
To be more specific I want to add items to listview from class that is different from partial class but in same namespace.
I tried like this:
public partial class Aa : Form
{
public static void UpdateListView(string[] array)
{
if (ProcessNetUsageList.InvokeRequired)
{
ProcessNetUsageList.Invoke(new Action<string[]>(UpdateListView), array);
}
else
{
ListViewItem item = new ListViewItem(array[0]);
for (int i = 1; i < 4; i++)
item.SubItems.Add(array[i]);
ProcessNetUsageList.Items.Add(item);
}
}
}
and then access it from another class like:
class Test
{
test()
{
ProgramName.Aa.UpdateListView(someArray);
}
}
But its giving an error because static method can only access static variables,and my listview isnt static(i created that listview in vs designer).
If i remove static keyword from method in partial class then i cant access it.I tried to create instance of partial class but without success.Any idea is welcome
note:Im using Invoke in my UpdateListView method because later that will be running on new thread
The nature of an object-oriented language is that objects don't have universal access to modify other objects. This is a good thing.
You've provided relatively little code so it's hard to provide a perfect answer here, but there are a few paradigms that resolve this issue.
One is to pass the instance to your test class, like this:
class Test
{
test(ProgramName.Aa form)
{
form.UpdateListView(someArray);
}
}
Or, if class test actually contains the ListView, you can pass that to a static method in Aa.
class Test
{
ListView someListView;
test()
{
ProgramName.Aa.UpdateListView(someListView, someArray);
}
}
Ultimately, you should think about the logical relationship between these objects to determine how these objects should communicate.
Remove the static keyword from UpdateListView, as you have done before. In test(), you need to instantiate Aa before you access UpdateListView.
Aa temp = new Aa()
You can then access the method by using
temp.UpdateListView(someArray);

Having trouble with C# form passing

I'm currently trying to get into C#, after doing a ton of Java. I wanted to pass my GUI Form to another class, but I run into some trouble trying to access its containers etc. from there.
This is the autogenerated Form class:
namespace Wecker
{
public partial class WeckerDesign : Form
{
public WeckerDesign()
{
InitializeComponent();
new WeckerRun(this);
}
}
}
and this is the recieving class:
namespace Wecker
{
class WeckerRun
{
WeckerDesign wdesign = new WeckerDesign();
public WeckerRun(WeckerDesign wdesign)
{
this.wdesign = wdesign;
new DisplayClock(wdesign);
}
}
}
However, when I am trying to access the container "clockfield" from the recieving class, I can't find it. However, in the passing class, I can easily get there with this.clockpanel. ... and so on.
The recieving class won't even suggest me that. In Java, I would simply pass down my class as a whole with "this" in order to have the exact same reference in the other class, which I can treat as if I would do it in the original class where I got that object reference from.
How do I do this in C#?
How is your "clockpanel" field or property defined? It will need to be public to be accessible from outside the class.

Access Parent/Owning class variable from composed class?

Forgive me because I know my wording is terrible. I'll just give an example.
public class MainClass{
public int someVariable;
public List<HasAClass> cList = new List<HasAClass>();
addHasAClass(HasAClass c){
cList.Add(c);
}
}
public class HasAClass{
public HasAClass(){
//Modify someVariable in some way????
}
}
public class HasASubClass : HasAClass{
public ComposedClass(){
//Modify someVariable in some way???
}
}
I having trouble finding the right words for this questions but here is what I am trying to do:
I am creating an aid for an RPG similar to dungeons and dragons. Each character can have a variety of special abilitys which can effect the characters in some way (both negative and positive). I am trying do this with a variety of subclasses which store the pertinent info and get added to the character at varying points in time. What I can't figure out is how to modify the properties of the Character(I called it Main Class in my example) when instances of the HasA class are added to it.
The HasAClass needs a reference to the owning instance, so that it can ask the parent for values and update them when required...
public class HasAClass
{
private MainClass _mainClass;
public HasAClass(MainClass mainClass)
{
_mainClass = mainClass;
_mainClass.someVaraible = 42;
}
}
You then need to pass the owner reference into the constructor of the HasAClass when they are created. If this is not possible at the time of creating the instance then you would instead need to assign it as a property after it has been created. Such as inside the addHasAClass method.

class variable gets reset when calling methods in multiple forms

Updated to reflect to my own source
I'm in process of building my first winform application in c# and I'm trying to figure out the best practice for structuring my classes to work smoothly when I use them in my forms.
I have a couple of examples which I will try to explain the best way i can.
When working with get/set variables in a class, the best practice should be something like this:
JobMove.cs
public class JobMove
{
private List<string> jobNames { get; set; }
public string Scanner;
public JobMove()
{
this.Scanner = Properties.Settings.Default.Scanner;
}
public void ListSelected(ListBox lbx)
{
foreach (string jName in this.jobNames)
{
lbx.Items.Add(jName);
}
}
public static List<string> GetCheckedJobs(ListView lw)
{
int countChecked = lw.CheckedItems.Count;
int itemCount = 0;
List<string> jList = new List<string>();
foreach (ListViewItem item in lw.CheckedItems)
{
JobInfo jobInfo = Job.Find(Convert.ToInt32(lw.Items[item.Index].SubItems[1].Text));
jList.Add(jobInfo.Name);
itemCount++;
}
return jList;
}
}
My problem is when I combine this with my forms and I call this, then I would try to do something like this:
MyForm1.cs
public partial class MyForm1 : Form
{
private void btnMoveJobs_Click(object sender, EventArgs e)
{
Properties.Settings.Default.Scanner = cbxScanners.SelectedItem.ToString();
JobMove moveJobs = new JobMove();
frmMoveJobs FrmMoveJobs = new frmMoveJobs();
FrmMoveJobs.ShowDialog();
}
}
MyForm2.cs
public partial class frmMoveJobs : Form
{
public frmMoveJobs()
{
InitializeComponent();
JobMove moveJobs = new JobMove();
lblFrom.Text = moveJobs.Scanner;
moveJobs.ListSelected(lbxJobsToMove);
cbxMjScanners.DataSource = System.Enum.GetValues(typeof(Scanners));
}
}
But when I call MyClass in MyForm2 and I want to call the DoSomethingElse method, then myString will be reset to a null value. And that makes sense to me, but how do I work around this?
I tried to figure out what to use here to get easier around these flaws in my code, but my knowledge is far too weak to just implement an easy solution.
I know I could just store this variable in Settings.settings as an example, but to me that just seems like a real overload for such a simple task.
I might just need a point in the right direction to right on what to do in this situation.
If you do a MyClass myClass = new MyClass(); then indeed - the values are independent and unrelated. If you want to share the MyClass instance then pass the MyClass instance between the forms. Perhaps:
using(var form2 = new Form2()) {
form2.SensibleName = existingMyClassInstance;
form2.ShowDialog();
}
(note the using above btw; when using ShowDialog() it is your job to make sure the form is disposed; it only gets disposed automatically if using Show())
Firstly, they're properties, not variables (the variables are the underlying data source).
Secondly, the whole point of get/set accessors is so you can get and set the value without needing helper methods.
Thirdly, and as to your problem, you're creating a new instance of the class in each form (hinted at by the new keyword) and the value of the property will be whatever it is initialised as on construction of the instance (or not.) i.e. the values of properties are not shared between different instances of the same type.
Think of the mold for a key: I can get multiple instances of the key cut from a "blueprint", but any damage that one suffers won't be reflected by the rest - they're unique in that sense.
If you want the forms to both access the same instance of that type, then you will need to stash the instance somewhere in your code which is accessible to both.
A few options:
Pass in an instance of MyClass in the form2's constructor.
Make MyClass a static property of either Form1 or Form2 and access it via that on the other form.
Make MyClass static (not recommended).
If you want to use the instance of MyClass created in MyForm1 inside of MyForm2, you need to provide it to MyForm2.
Something like this would work:
public partial class MyForm2 : Form
{
public MyForm2(MyClass given)
{
InitializeComponent();
given.DoSomethingElse();
}
}
Easy Solution:
private static string myString { get; set; }
Why: because you initialize the class again when initializing Form2 and it will create a new class. With the "static" keyword you create a property which is the same in all instances of this class.
BUT: please read some books before continuing, this would be the solution to this problem, but the source of many others. Try to understand C# and Forms first, than (or alongside with reading/learning) start coding!
this is because each of your form has a new object of "MyClass".
To achieve what you want to do use a static property... this won't be initialized and gives back the same value for each object of MyClass
it looks like this
public class MyClass {
public static string myString { get; set; }
public void ChangeMyString(string newString)
{
myString = newString;
}
public void DoSomethingElse()
{
MessageBox.Show(myString);
}
}

Categories