Is it okay to refer to "this" in the constructor? - c#

In C#, a common pattern that I use is to populate the details of a lower calculation class with a form object.
The constructor for MyForm is:
MyForm()
{
_MyFormCalcs = new MyFormCalcs(this);
}
But I encountered an error today which makes me think that as my constructor had not finished completing, it creates a new instance of MyForm to pass into MyData. Thus it calls the constructor twice. I found that a static list in MyFormCalcs was being filled twice and was failing the second time as the keys were already present in the list.
Can I use this in the constructor to refer to this instance? What will it contain in the lower class - has the constructor been run or not.
What is a better way of passing my form into the lower class?

No, that won't create a new instance of MyForm.
In general, allowing this to "escape" from a constructor is dangerous as it means it can be used before the constructor has completed, but it's not going to be creating a new instance. If you could give a short but complete example of the problem you've seen, we could help diagnose it further. In particular, it's not clear what you mean about the "static list being filled twice". Usually it's not a good idea to populate a static variable in an instance constructor.

In fact, it is really nice to avoid such call inside constructor, because your object is not already built (constructor hasnt finish its work) but you are already use this "unfinished" object as a parameter. Its a bad way. Good way is creating some special method:
class MyClass
{
var obj:SomeClass;
public MyClass()
{
}
public Init()
{
obj = SomeClass(this);
}
}

Make a private property that instantiate MyFormCalcs only when it is first used, like this:
public class MyForm {
private MyFormCalcs MyFormCalcs {
get {
_MyFormCalcs = _MyFormCalcs ?? new MyFormCalcs(this);
}
}
}
This way, you don't have to think about when to "initialize" things.

There is this very complete response of C# constructor order:
C# constructor execution order

Related

What happen when new Instance of an object call?

There is one confusion in my mind, about the constructor of class. How ever I tried to find this but doesn't find any answer relevant to my confusion..
Suppose I have a class
public class mySampleClass
{
public mySampleClass()
{
// This is the constructor method.
}
// rest of the class members goes here.
}
which have many properties, when I initialize this class what happen? I mean to say whether only constructor is being called? or something else?
what about rest of the properties? i am asking this foolish question because of my WCF service, which contain many methods, in every methods I have initialize same class, if I make object globally it crashes some where.
My other question is how many time it takes to initialize new instance of constructor? depending of all code? or whether constructor body?
Please elaborate with some Example. with two constructor or many.
UPDATE :
There is some confusion Regarding this Question, I have simply share one Scenario like WCF services, but I have to known all over constructor initialization Time, whether it depends on constructor? or all over object (containing other methods properties).
In simple words
I want to know constructor behaviour when it is initilize whether it is depend on Properties, Method etc?
Constructor gets executed only once and it's when you instantiate your class in other classes or methods or even in your service.
ex.
mySampleClass msc = new mySampleClass();
Properties and Methods inside the class won't be affected "unless" you do something like msc.PropertyName="somethingelse"; or msc.MethodName();.

Class Member Instantiation

public class ClassA
{
private SomeOtherClass _someOtherClass = new SomeOtherClass();
}
or
public class ClassB
{
private SomeOtherClass _someOtherClass;
public ClassB()
{
_someOtherClass = new SomeOtherClass();
}
}
or
public ClassC
{
SomeOtherClass _someOtherClass
public SomeOtherClass someOtherClass
{
get{
if(_someOtherClass == null)
{
_someOtherClass = new SomeOtherClass();
}
return _someOtherClass;
}
}
}
All of the above accomplish populating a property with an instance of an object. Is there a benefit to one of them over the other ones? In practice, I only use C when I don't have control over the construction of a class (like in a GUI). A smells a bit to me, but I don't have a concrete reason for that smell.
Note I am omitting the Inversion Of Control (IOC) pattern from the discussion as the benefits of that are well known and I of course use it often. This question is more about the case of a simple class that may not need that pattern.
A and B are almost the same (implementation details on the order, but not important in this case).
I would use C when:
The initialization of the variable can be delayed, or isn't frequently used;
I want to optimize the initialization time and memory of the class.
Another option for C is the use of Lazy<T>, but that is out of scope for the question I think.
A and B are (as said in other answers) basically the same. The property is populated when the class is constructed.
C doesn't populate the property on construction of the class, but only when it's accessed, which can be useful for a number of reasons (for example performance). Furthermore, it also has the side-effect that the property will never be able to be 'null' (whenever it's accessed, which could be an advantage or a disadvantage, depending on what the property is used for.
Well, the first and second example works the same, but I can say that the second one is much cleaner than the first one, because the instantiation is in the constructor, and the purpose of the constructor is usually to initialize the object's members that can be defined at that moment. In this way, you can easily know what has been instantiated just by looking at the constructor, and not searching through all the fields. In any of the first two cases, you could mark the field as readonly if you don't change it's value after that.
I see the third one as a kind of lazy loading, because you will initialize the field when you get the property. I use this when I am not sure if I will use the object within the class, so it is created per request. However, it has the minimal overhead of checking everytime if the field is instantiated, but it's nothing to worry about with current hardware. If you will use the object only within the class, you can mark the property as private, because it has no reason to be seen from the outside.

Using the "this" keyword in a different class c#

I made a program that works just fine as-is, however i want to organize code better by moving some of my logic into other .cs files; upon moving some code i noticed that code reffering the "this" keyword for changing the applications width / height no longer function and ive had no luck trying to get a handle to "this", please help
int heightd = (int)this.Height;
Edit: To further clarify. My mainwindow.xaml.cs is where all my code was before.
I would use this.width to get my windows width.
Upon creating a different .cs file to hold related methods, it broke all of my "this" refferences.
I want for my NEW cs file to be able to get a handle on "this" from my main program. so i can call its width, height, etc
Re-edit: I understand that "this" is not going to function properly from my new class I just want to be able to create methods that use the same object that is accessed when "this" is refferenced.
So for example, Class2 can do WorkAround.height ; where WorkAround is a handle to whatever "this" is in class 1.
Soution: updated signature in new class to accept the main window:
public static void Marginnn(MainWindow aplication)
{
send "this" from main class during the call:
WindowsInterop.Marginnn(this);
Others have discussed partial classes, which can be problematic. For this answer, I assume by "move to another .cs file" you mean "move to another class," as your title indicates.
The this keyword is effectively a variable that refers to the instance that "owns" the current method. If the method is moved to another type, then the instance can no longer be the owner of the method. Instead, you need to pass a reference to the instance into the method instead. That will be a method parameter, which will have a name other than this.
Example; before:
class App
{
public void DoSomethingWithTheHeight()
{
int heightd = (int)this.Height;
//more code
}
public void CallDoSomethingWithTheHeight()
{
this.DoSomethingWithTheHeight();
}
}
Task: move DoSomethingWithTheHeight to a new static class:
class App
{
public void CallDoSomethingWithTheHeight()
{
NewClass.DoSomethingWithTheHeight(this);
}
}
static class NewClass
{
public static void DoSomethingWithTheHeight(App application)
{
int heightd = (int)application.Height;
//more code
}
}
Task: move DoSomethingWithTheHeight to a new non-static class:
class App
{
public void CallDoSomethingWithTheHeight()
{
NewClass instanceOfNewClass = new NewClass();
instanceOfNewClass.DoSomethingWithTheHeight(this);
}
}
class NewClass
{
public void DoSomethingWithTheHeight(App application)
{
int heightd = (int)application.Height;
//more code
}
}
There are other possibilities, but these examples should illustrate the basic principle.
If you only want to move part of your class to another file and still use this, you have to use a partial class. But I won't recommend this approach, your code clearly needs some refactoring.
C# keyword this refers to the current instance of the class it's being used in. It can be used for a few other things such as a modifier of the first parameter of an extension method, but we won't worry about that here. So, you may only use this from within the class that it's referring to and note that it may not be used with static classes, methods, fields, etc... since they have no instance associated with them.
If the code you're referring to is not implemented within a partial class, then it has to refer to the instance of the Window. Otherwise, it's impossible to tell what this is. Since we don't know how exactly you're structuring your program, it's hard to recommend a method of fetching the instance of the Window in question. If, for example, you would use the MVVM pattern, you wouldn't even need to interact with the instance of the UI from within the code. However, if you're working with a code-behind model, then your best bet is probably to create a partial class for that window. Like I said, it's hard to know what's right in your situation without knowing the entire scope of your environment.
There are lots of ways to tackle this and some are more hackish than others:
// In the code-behind of a window...
public static MyWindow Instance { get; private set; }
public MyWindow()
{
Initialize();
Instance = this;
}
// Somewhere else in your program...
var someValue = MyWindow.Instance.SomeControl.Value;
Note that the above code is just for demonstration purposes and not something I would recommend doing (it doesn't even account for null, but that's easy to fix). It's simply a demonstration showing that there are almost countless ways of tackling your problem. Ideally, if you're not going with MVVM, I would probably implement a window manager class that handles instances of all of your application windows.

Where to create singleton instance if I don't need this instance in my program?

Assume I have some singleton that just need to be instantiated. In constructor it starts timer, and updates some model data each second.
To execute singleton constructor I just need to reference it. I don't need resulting instance because I don't need to do anything with singleton it should exist during entire application execution.
However c# doesn't allow such construct: WcfLoader.Instance;
So I have to use this WcfLoader loader = WcfLoader.Instance; but i never use loader instance.
It looks odd, does it mean that I do something wrong?
Add a static Init method to your class, then call WcfLoader.Init instead of getting an instance. It won't look weird at all.
Don't make this a side effect of getting the Instance property. Getting a property should not have side effects.
Add a method InitTimer() or something like that on the singleton.
You could also involve the instance constructor:
public class WcfLoader {
static WcfLoader _instance;
public WcfLoader() {
if ( _instance == null ) {
// do the initialization
_instance = this;
}
}
}
Then the initialization consist in calling the constructor without even storing the reference anywhere.
// just create a new object which causes the initialization code to execute
new WcfLoader();
Of course the explicit initialization method (as mentioned by others) is a best choice.

Calling instance method from a constructor in C#

I have a rather lengthy constructor which is performing various initialisation work, and as such I wanted to factor out some of this work into some functions. This led to me wonder whether I should make the said functions instance or static methods. I understand the risk of calling a virtual function from a constructor but I also think there is something not right about calling an instance method on an object which is not 100% instantiated. Surely this is a contradiction in terms.
I'd be interested in peoples opinion on this matter. I also found that by using a static method to return an initialised variable I could make the member target read-only. Here's a simplified illustration of my scenario.
public class A
{
private readonly string _foo;
public A()
{
_foo = InitialiseFoo();
}
private static InitialiseFoo()
{
// Do stuff
return new string ("foo");
}
}
This is pretty normal to call instance method in a constructor, moreover method which doing Initialization. So basically this is a kind of Extract Method refactorig to reduce a constructor method body, so you are extracting part of initialization into a separate method and constructor is aware on saving of the input arguments, etc...
Regarding the static modifier.. sometimes (I believe when no other ways to refactor because this looks not good - from my point of view) you need to call a method to pass results in a base constructor so in this case you have to mark it as static to call in a static context in other cases leave it without the static modifier
public A()
: base(GetLogger())
{
}
private static ILog GetLogger() ...
I can understand the desire to only use static members in a constructor, because it DOES make the code more straightforward to use without having to track what has been initialized and what hasn't, but you're likely making things needlessly complicated for yourself. Calling an instance method in C# is fine as long as you have a good reason to do it. For instance, if you have a number of constructors that all perform some common tasks, creating a single member function to do the work is easier to maintain than copy-and-pasting the code for each constructor. You can also imagine a case where the method can be re-used outside of the constructor for something like reseting the class to the initialized state.
The static method, is fine, but will only work in the case where you are doing some isolated work and putting the result into a member variable. It provides a very clean, functional programming-like feel. If any of the work involves class state, however, it's going to get ugly.

Categories

Resources