prevent unassigned objects, any reason this is a bad design consideration? - c#

In my WPF application, I have a few places that based on a given ID of a record, I call a new form to be displayed as modal to view details. It then closes and returns back to calling source as expected. All this works no problem.
To keep this simplified in coding, I put a "ShowDialog()" call at the end of the constructor of the form being displayed. This prevents the need of every place that this form being called requires something like..
var myModalForm = new MyModalForm(someIdToDisplay);
myModalForm.ShowDialog();
Simplified, I just need to create the modal form with the Id, such as
new MyModalForm(someIdToDisplay);
But through the ReSharper inspector, it comes back with "Possible unassigned object created by 'new' expression".
I know the garbage collector will get it when it's finished, but being a modal form, once it's done, I don't need to do anything else with it. So, is this bad, or ok and just ignore this type of warning consideration. Everything else works fine in the application otherwise.

To keep this simplified in coding, I put a "ShowDialog()" call at the end of the constructor of the form being displayed.
That sounds like an ugly design to me, personally. Constructors are designed to return a usable object - and ideally that's all they should do.
I would change this to a static method in MyModalForm:
public static void ShowForId(int id)
{
var form = new MyModalForm(id);
form.ShowDialog();
}
Then your calling code can just be:
MyModalForm.ShowForId(someIdToDisplay);
Now it's clear what it's trying to do: the purpose is to show a form, not just create it.

Related

C# control not going into the method

I am trying to call a private method from another private method like this
UploadFeeScheduleToDb(147, finalPath);
Method definition:
void UploadFeeScheduleToDb(int UploadID, string UploadFilePath)
{
DataSet CSVData = CSVToDataSet(UploadFilePath);
}
The problem is that the C# control is coming to the method call but not going inside it. I added breakpoints like this:
As you can see, the control is reaching the breakpoint but it's not reaching to the second breakpoint inside that method. It's just skipping to lblMsg.Text... statement without any exceptions in output window.
I tried cleaning solution and rebuilding. Also, I passed constants or magic values to the method. But no luck. I don't know what is happening?
As #Silvermind and #HenkHolterman said, the UploadFeeScheduleToDb method is not doing anything productive except assigning the value to its local variable, the C# compiler will ignore this method when Code Optimization feature is turned on. I think this is called Dead Code Optimization. Correct me if I am wrong.

"Click" - Delegate to an instance method cannot have null 'this'

I know there are alot of questions allready to this topic. But I can't really seem to understand this whole delegate stuff. I'm kinda at a point where I just want it to work and move on. Everytime when I look at delegates I think to myself, there has to be a way to make this much easier to understand and do, but I can't seem to find it.
I have a FlowLayoutPanel that will be filled with a bunch of Panels. each of those panels needs to have a OnClick (or Click?) method to be attached to it.
So I went ahead and wrote (inside of the creator of my personal panel class):
IntDrawForm form = FindForm() as IntDrawForm;
Click += form.PointPanelClick;
And I ended up with the error message Delegate to an instance method cannot have null 'this' when tried to create one my panels.
Yes, that will happen if FindForm() returns either null, or something that isn't an instance of IntDrawForm. There's nothing particularly specific to delegates here - you'd get a similar result if you tried this as your second line:
form.CallSomeMethod();
(In that case it would be a NullReferenceException.)
Given that the second line basically fails when form is null, you shouldn't use as here - use a cast instead. That way, the first line will fail if you don't have an IntDrawForm, and you'll get a more informative exception.
IntDrawForm form = (IntDrawForm) FindForm();
Now we can't tell why FindForm() has returned either null or a non-IntDrawForm, but that's a different matter.

Subsequent method calls to same method enters a new context?

I have a question regarding method calls and stack pointers.
Basically I have a program that reads input from the user. After creating an object of a class "Input", a method call "prompt()" presents a menu with choices, and each choice you make calls a new method that performs some operations. After making a choice, you can always choose to go back to the main menu, and this action calls "prompt()" again.
Now, my question is, will each call of "prompt()" point to a new place in the memory stack or will it enter the same context as when the first call was made? I.e is it possible to create a memory leak by going back to the main menu over and over?
class inOut {
public string[] Prompt(){
...
presentChoices();
...
}
private void PresentChoices(){
...
if(someChoice){
manualInput();
}
...
}
private void ManualInput(){
...
if(goBack){
Prompt();
}
...
}
}
I hope the question was clear and thanks in advance for any answers on this!
For each method you enter there should be a corresponding return. Otherwise it may lead to StackOverlow. It's not a new context, but a values left in stack, which are used for return to return to the point where method was called and for method call itself (to pass parameters).
To have something repeating itself you can use infinite loop:
while(true)
{
... // repeat this action
if(endcondition)
break;
}
In your case repeated action is call to prompt() to show menu. It may have return value to tell whenever repeat or exit, which you use in endcondition.
As Long as you call the method on the same object instance, it's going to be the same pointer to the same adress.
When you create new instances of an object each object has it's own pointer.
If you want to avoid that then you need to define the method as static. In this case you will call the method not from an instance but from the type.
Something you need to be careful about especially when you call the same method over and over again from the same instance context are recursive calls. To many recursive calls (many thousands) will result in a StackOverFlowException (like the Name of this website). You can find out if you have recursive calls in the StackTrace pane in Visual Studio or if you have Resharper installed it will tell you on the left side of the document.
Either way, what you are describing here is not really a "Memory Leak" (ML's are unused objects that do not get collected and stay in memory not doing anything) but rather a stack Overflow Situation.
Objects that are not referenced anymore are garbage collected.Thats what will happen to your Input object.
Unlesss...
... you do it wrong.
In Winform applications doing it wrong usually happens when there are eventhandlers involved that for some reason (the publisher of the event lives longer than the subscriber) prevent the garbage collection.
Suppose your code looks something like this:
void Prompt()
{
// ...
var obj = new Input();
// ...
if (someCondition)
{
Prompt(); // recursive
}
// ...
// Is 'obj' used here?
}
Then when you call Prompt() recursively, yes, a new context is created. The obj variable will point to a new object, etc.
If the recursion becomes very, very deep, you might get a StackOverflowException (no more space on the stack for new "call frames"), or you might get an OutOfMemoryException (no more heap space for Input instances).
However, if you know for some reason that the recursion will not become too deep, the Garbage Collector will clean things for you when it is safe to do so.
But maybe you should consider a while (or do) loop instead of having your method call itself? It really depends on what you want to achieve.
I may have misunderstood your question. Maybe Prompt() is not called from within Prompt itself? You should give simplified structure of your code (like my code sample above) to make it clear what calls what from where.

Collection of Subroutines or Dynamic Reference to Sub in C#

I'm working with a VSTO, that uses a whole lot of buttons on a work sheet. I had problems with the ActiveX controls going missing if I tried to just have them stored in the workbook. To fix that, I'm making all the buttons at runtime. Not supper elegant, but I have function to help me with that:
public object MakeOButton(double LL, double TT, string ButtonName, params object[] ActionArray)
{
Microsoft.Office.Tools.Excel.Controls.Button ButtonXX = new Microsoft.Office.Tools.Excel.Controls.Button();
string ActionCall = ButtonName + "_Click";
ButtonXX = this.Controls.AddButton(LL, TT, 18.75, 14.25, ButtonName);
ButtonXX.Click += Interaction.CallByName(this, ActionCall, CallType.Method, ActionArray);
return ButtonXX;
}
I then call this for all the buttons I want to make, and it drops in the right place and names them accordingly. What I'm having trouble with is setting each one of these buttons to the correct click interaction.
Each button should be handled by a different routine which has the name [ButtonName]_Click. I was hoping to not have to declare each button before hand, especially if I want to be dynamically changing which buttons are called.
To do that I need find some way to refer to the subroutine associated with the button dynamically. At the moment, the only way I can think I might have chance is using the string ButtonName_Click to refer to the subroutine. My thought was ether through a collection of all the subs that are in the worksheet, or to be able to refer to it directly.
My best idea (which is in the above code) successfully calls the sub dynamically, but doesn't set the interaction to the click, it just make's it click at creation:
ButtonXX.Click += Interaction.CallByName(this, ActionCall, CallType.Method, ActionArray);
I feel like I must be so close to the right answer. Any help would be appreciated.
The Interaction.CallByName method is actually invoking the method immediately. What you need to do is set it up so that it's called when the Click occurs. The easiest way to do that is to use an anonymous method
ButtonXX.Click += delegate {
Interaction.CallByName(this, ActionCall, CallType.Method, ActionArray);
};
This creates a method that will be called when the Click event happens. At that time the body of the method will run and execute Interaction.CallByName

Creating a method for an operation in a separate class file

I'm trying to call a method from a different class but with no succes.
I have a CheckBox checkBox1 in my program, and I have a button that when I click it I want to uncheck the checkBox1.
If I put I method in the same file like this everything works:
public void close()
{
checkBox1.IsChecked=false;
}
But if I create a separate class file (class Close), and put there (in the same namespace, and with "using" the required elements). There no way to make it work. I tried to instance the class as:
Close operation = new Close();
operation.close();
I also tried to put the close method as static, but I was impossible because in my real program I have lots of variables that gives me an error because they are "non static" (?).
I've noticed that a MessageBox.Show("Hello"); works if I call the method this way, but the checkBox1 still unchanged. What can I do?
A basic principle of Object Oriented Programming is Encapsulation. It means that a class knows and operates only on the internal member variables of the class.
In your case the class Close doesn't know anything of the control variable named checkBox1 and thus, the method close (as written above) cannot operate. It could not even be compiled!. Instead, when the method close is part of the Window class it works as expected because the control variable checkbox1 is a member variable of the window class
However, if I understand your intentions, I advise you to avoid to create separate classes to handle user interface operations. Let the code that works with the UI elements stay with the class where the elements are defined.
The CheckBox.IsChecked returns a value of type bool, if you are trying to actually change the value of the check box (i.e. checked or not-checked) you need to use a different property.
Try:
public void close()
{
checkBox1.Checked = true;
}
This is assuming that the Close class indeed has a CheckBox control inside of it... your question is rather vague, and frankly naming a method close is probably not the best practice as .Close() is a fairly common method on many classes in WinForms.

Categories