C# - Determine if class initializaion causes infinite recursion? - c#

I am working on porting a VB6 application to C# (Winforms 3.5) and while doing so I'm trying to break up the functionality into various classes (ie database class, data validation class, string manipulation class).
Right now when I attempt to run the program in Debug mode the program pauses and then crashes with a StackOverFlowException. VS 2008 suggests a infinite recursion cause.
I have been trying to trace what might be causing this recursion and right now my only hypothesis is that class initializations (which I do in the header(?) of each class).
My thought is this:
mainForm initializes classA
classA initializes classB
classB initializes classA
....
Does this make sense or should I be looking elsewhere?
UPDATE1 (a code sample):
mainForm
namespace john
{
public partial class frmLogin : Form
{
stringCustom sc = new sc();
stringCustom
namespace john
{
class stringCustom
{
retrieveValues rv = new retrieveValues();
retrieveValues
namespace john
{
class retrieveValues
{
stringCustom sc = new stringCustom();

9 times out of 10, infinite recursion bugs are caused by bad property accessors:
public class BrokenClass
{
private string name;
public string Name
{
get { return name; }
set { Name = value; } // <--- Whoops
}
}
I've also had it happen when doing major refactorings with method overloads; sometimes you accidentally end up with a method calling itself when it's supposed to call a different overloaded method.
Either way, you should be able to tell by looking at the call stack for the exception and checking for a repeating pattern. If you see one, then your problem is somewhere in that loop.
Edit - well, based on your example code, you definitely have infinite recursion in the initializers. I have no idea what that code is supposed to be doing, but it's never going to terminate. StringCustom immediately creates RetrieveValues which immediately creates another StringCustom, and so on.
This is one reason why circular class dependencies are typically considered a code smell. Whenever you see ClassA depending on ClassB and ClassB depending on ClassA then you should try to refactor; the exception is if ClassB is entirely owned and managed by ClassA (i.e. an inner class), which is clearly not the case here. You need to eliminate one of the dependencies somehow.

Just put a break point in the constructor of each class you initialize. If you keep accessing the same breakpoints over and over again, I would say infinite recursion is the cause.
I would also check the stack to see what is going on.

Yes, you have an infinite recursion going on because you have two classes which create an instance of the other class in their constructors. As soon as you create an instance of one class, it creates an instance of the other class, which creates an instance of the other class, which creates an instance of the other class etc. etc. etc.
You definitely need to refactor this.

Yeah, I think you are likely on the right track. You can sometimes see this easily in the debugger by looking at the call stack on a break point put at the line of code that causes the exception.

Sound like that is the issue. Can you not pass ClassA into the constructor for ClassB?

Well, everybody understands it. Why not suggest some solution then?
Now, I remember this situation. One way is to avoid calling another contructor inside one. So, there would be extra coding. Eg -
class A {
B b;
A() {}
void Init() { b = new B(); }
}
class B {
A a;
B() {}
void Init() { a = new A(); }
}
...
A aObj = new A();
aObj.Init();
...
B bObj = new B();
bObj.Init();
This will remove the recursion. This is, obviously, easiest way. :)

Related

Confusion regarding the 'new' keyword in C#, Unity

Maybe a silly question, but having difficulty understanding it.
public class A
{
public void Message()
{
Debug.Log("Some Message")
}
}
public class B: MonoBehaviour
{
A obj1 = new A(); //instance of object is made and constructor is called
A obj2; // object is made
obj1.Message();
obj2.Message();
void Start(){}
void Update(){}
}
What's the purpose of 'new' keyword if in both cases, the object is able to use methods of the class
A obj2; // object is made
The object is not instantiated at this time, you only told here that you have a variable with the name obj2, and it is hold reference to nothing, in case of class it is null. You have a class named A and in it, you have a method called Message() and compiler in compile-time have a signal you have Message method defined, and that it is. In this case, this code should throw an exception NullReferenceException
There are a few quirks to Unity which may be tripping you up here. Actually, obj2 is not null, because it is of type "A" (not a Monobehavior). Since Class B is derived from Monobehavior, all of its "class variables" (the ones defined in immediate scope) will be instanced by the Inspector automatically. You can read about that here.
In other words, obj2 will still be usable. This is a property of custom classes in regards to how they are loaded from MonoBehaviors. If class A was also a MonoBehavior, then it would be nullable here, and you would see it as an empty variable in your inspector when Class B is put onto a GameObject. This is the case where Message() would not work, since obj2 would actually be null. Note there are other complications though--if Class A is a MonoBehavior, then you shouldn't be using Constructors on it, you should be using AddComponent(). Also, you can't define two MonoBehaviors in the same script file.
Finally, I'm not sure of the specifics here since I haven't tested it, but obj1.Message() may not be able to be called from where you're currently doing it. Typically code is run using the Callback functions provided by the MonoBehavior inheritance, i.e. Start(), Update(), etc. In order to call obj1.Message() at the start of the game, you need to run it from the Start() method. Let me know if you have any questions and I can clear up anything you find confusing!
EDIT: This is only true if obj2 appears in the inspector--if it is public and the class A is tagged as Serializable.

C# Warning: Variable is assigned but never used

I see this warning in a lot of places in my code because of a specific paradigm I keep using throughout. Within objectA, I create objectB and objectB does a lot of it's own work that is necessary, but not referenced anywhere else.
The only answers to this question I see are:
Suppress the warning
You are doing something wrong.
Example of what I'm doing in lots of places.
class A {
B b;
public A() {
b = new B();
}
}
class B {
public B() {
Updater.RegisterForSuperImportantUpdates(this);
}
public void Update() {
// super important stuff happening here
....
}
}
Does this seem like a valid design or is there an off putting odor here. Suppressing the warning is going to be annoying because this pattern is going to be used frequently.
Why do you want to keep a reference to b(B) if you are not using it after?
Can't you just new it without keeping it referenced?
As it seems to be referenced by a third class not mentioned here (Updater), it should not be GCeed.
It is a valid warning , as per clean code principle , you should keep your code as much neat and clean such that the second person who will be going to fix in your code should not confused with the unused variable used in the code.

c# Do I have to specify name for a new class instance?

I'm making a simple game in unity and have a small uncretainity you could help me with:
do I have to name the new instance of a class?
for example:
public class CreateCharacter : MonoBehaviour {
public string charname;
public CreateCharacter (string charname)
{
this.charname = charname;
//does all the stuff needed
}}
I want to run this from another script:
int e = data.Length - 1;
if (e > 0)
{
new CreateCharacter(data[e]);
e--;
}
data is a string array and CreateCharacter will store the new Character object in a list of such objects, so I can accss it later. My question is:
Do I have to write:
CreateCharacter SomeName = new ChreateCharacter
for the code to run? or is simple
new Class (constructor)
enough?
While it is poor practice to new something and not toss it in a variable, that code WILL compile and run just fine. Additionally, is there a reason you have a class called CreateCharacter? Instead of a function that returns an actual character given the data?
You are allowed to call the constructor by itself like you stated. However, do keep in mind that the newly created object will immediately fall out of scope and be deallocated after the constructor is done. So depending on what's included in "// does all the stuff needed", it could -potentially- crash your app (although it would be unlikely).
As stated in other answers, it is a best practice in both readability and functionality to assign the newly created object to a variable, even if only for the scope of that for loop.
It won't cause the program to die using without storing it.
new CreateCharacter(data[e]);
but yes, you want to store it so you can call methods on it like
CreateCharacter char = new CreateCharacter(string);
char.methodName();
Your other option is to put the code you are trying to execute in a static method because it seems that the code you are running in the constructor is not dependent on the instance of the class CreateCharacter.
If you use
new Class (constructor)
it is anonymous object and it does the job. This king of object is used whenever the object is not referenced from other places of your code and its benefit is that you are not supposed to find an appropriate name for that.

Delayed setup in C# constructor

Hello I was wondering how I can setup several things in a constructor, but have it wait until right after the object is created. I am thinking along the lines of my C++ and QT days when I would create a singleshot timer for 0 seconds that would fire my setup method as soon as the object was constructed. Can I do that in C#?
I don't mind doing all the work I do in the constructor just simply seeing if there is a better way.
In C# whole object is created before executing constructor - all fields are initialized with their default or initial values (if any). If you want to delay something, consider using lazy initialization.
I'm not sure what the problem is with just putting your stuff in the constructor is - there is nothing you cant do. Maybe an example of why you would like to do this / what problem you are having, would allow us to give you a more suited answer.
Although if you really need to delay code,
public constructor()
{
Task.Factory.StartNew(()=>
{
Thread.Sleep(...delay...);
//delayed code
});
}
One way to do what you are asking is to have a static method that constructs the desired object:
class MyObject {
private MyObject() {
}
private void Setup() {
// do some configuration here
}
public static MyObject CreateObject() {
MyObject obj = new MyObject();
obj.Setup();
return obj;
}
}
Thus, you never use the class' actual constructor but instead invoke the static method that creates the object and sets it up at the same time. I am not sure why you would want to do this though, since the effect from the point of view of the caller is the same -- you wait until the object is created and its setup is complete to be able to use it.

Does a reference to a delegate constitute a reference to an object (to prevent garbage collection)?

I had trouble coming up with a good way to word this question, so let me try to explain by example:
Suppose I have some interface. For simplicity's sake, I'll say the interface is IRunnable, and it provides a single method, Run. (This is not real; it's only an example.)
Now, suppose I have some pre-existing class, let's call it Cheetah, that I can't change. It existed before IRunnable; I can't make it implement my interface. But I want to use it as if it implements IRunnable--presumably because it has a Run method, or something like it. In other words, I want to be able to have code that expects an IRunnable and will work with a Cheetah.
OK, so I could always write a CheetahWrapper sort of deal. But humor me and let me write something a little more flexible--how about a RunnableAdapter?
I envision the class definition as something like this:
public class RunnableAdapter : IRunnable {
public delegate void RunMethod();
private RunMethod Runner { get; set; }
public RunnableAdapter(RunMethod runner) {
this.Runner = runner;
}
public void Run() {
Runner.Invoke();
}
}
Straightforward enough, right? So with this, I should be able to make a call like this:
Cheetah c = new Cheetah();
RunnableAdapter ra = new RunnableAdapter(c.Run);
And now, voila: I have an object that implements IRunner and is, in its heart of hearts, a Cheetah.
My question is: if this Cheetah of mine falls out of scope at some point, and gets to the point where it would normally be garbage collected... will it? Or does this RunnableAdapter object's Runner property constitute a reference to the original Cheetah, so that it won't be collected? I certainly want that reference to stay valid, so basically I'm wondering if the above class definition is enough or if it would be necessary to maintain a reference to the underlying object (like via some private UnderlyingObject property), just to prevent garbage collection.
Yes, that reference remains valid, and can in fact be retrieved using the Delegate.Target property -- in your code, as ra.Runner.Target.
As others said it counts as a reference. You might find this story interesting.
http://asserttrue.blogspot.com/2008/11/garbage-collection-causes-car-crash.html
If not, that sounds like a broken garbage collector.
Yes, the delegate counts as a reference. Your object will not be garbage collected until the delegate is also unreachable.

Categories