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.
Related
Suppose I have a class that provides some data to my application. Data initially comes from database, and I provide it through some methods that handle the whole database thing and present the result as a usable class instead of raw query result. This class has to do some setup (not complex) to make sure any method called can use the database (e.g. connect to database, make sure it contains some critical info, etc). So, were I to put it in a method (say, method Init(), that would handle checking for database, connecting to it, verifying that it does contain the info), I would have to make sure that this method is called before any other method.
So, I usually find that instead of doing this:
public class DataProvider
{
private SqlController controller;
public void Init()
{
controller = new SqlController();
controller.Init();
controller.ConnectToDataBase();
CheckForCriticalInfoInDatabase();
}
public Data GetData()
{
// get data from database (not actually going to use raw queries like that, just an example)
var queryResult = sqlController.RunQuery("SELECT something FROM SOME_TABLE");
// and present it as usable class
Data usefulData = QueryResultToUsefulData(queryResult);
return usefulData;
}
...
}
and then always making sure I call Init() before GetData(), i do something like
private SqlController _controller;
private SqlController controller
{
get
{
if (_controller == null)
{
_controller = new SqlController();
_controller.Init();
_controller.ConnectToDataBase();
CheckForCriticalInfoInDatabase();
}
return controller;
}
}
So, now i can be sure that i won't use an uninitialised SqlController, and I don't have to do that same null check in every method that uses it. However, I never noticed getters being used this way in other peoples' code.
Is there some pitfall I don't see? To me it looks like it's the same as lazy initialization, with the exception being that I use it not because the initialization is heavy or long, but because I don't want to check the order in which I call methods. This question points out that it's not thread-safe (not a concern in my case, plus I imagine it could be made thread-safe with some locks) and that setting the property to null will result in unintuitive behaviour (not a concern, because I don't have a setter at all and the backing field shouldn't be touched either way).
Also, if this kind of code IS bas practice, what is the proper way to ensure that my methods don't rely on order in which they are called?
As #madreflection said in the OP comments, use a method for anything that is possibly going to be slow. Getters and setters should just be quick ways of getting and setting a value.
Connections to dbs can be slow or fail to connect so you may have catches setup to try different connection methods etc.
You could also have the checking occur in the constructor of the object, that way the object cannot be used without init() being run in a different function, saving on time tracing where an error is actually occurring.
For example if you had one function create the object, do a bunch of 'stuff' then try to use the object without running init(), then you get the error after all of the 'stuff' not where you created the object. This could lead you to think there is something wrong in whatever way you are using the object, not that it has not been initialised.
I have a class PluginProvider that is using a PluginLoader component to load plugins (managed/native) from the file system. Within the PluginProvider class, there is currently defined a property called 'PluginTypes' which calls the 'InitializePlugins' instance method on get().
class PluginProvider
{
IEnumerable<IPluginType> PluginTypes
{
get
{
//isInitialized is set inside InitializePlugins method
if(!isInitialized)
{
InitializePlugins(); //contains thread safe code
}
//_pluginTypes is set within InitializePlugins method
return _pluginTypes;
}
}
}
I am looking at refactoring this piece of code. I want to know whether this kind of initialization is fine to do within a property. I know that heavy operations must not be done in a property. But when i checked this link : http://msdn.microsoft.com/en-us/library/vstudio/ms229054.aspx , found this " In particular, operations that access the network or the file system (other than once for initialization) should most likely be methods, not properties.". Now I am a bit confused. Please help.
If you want to delay the initialization as much as you can and you don't know when your property (or properties) will be called, what you're doing is fine.
If you want to delay and you have control over when your property will be called the first time, then you might want to make your method InitializePlugins() public and call it explicitly before accessing the property. This option also opens up the possibility of initializing asynchronously. For example, you could have an InitializePluginsAsync()that returns a Task.
If delaying the initialization is not a big concern, then just perform the initialization within the constructor.
This is of course a matter of taste. But what i would do depends on the length of the operation you're trying to perform. If it takes time to load the plugins, i would create a public method which any user would need to call before working with the class. A different approach would be to put the method inside the constructor, but IMO constructors should return as quickly as possible and should contain field / property initialization.
class PluginProvider
{
private bool _isInitialized;
IEnumerable<IPluginType> PluginTypes { get; set;}
public void Initialize()
{
if (_isInitialized)
{
return;
}
InitializePlugins();
_isInitialized = true;
}
}
Note the down side of this is that you will have to make sure the Initialize method was called before consuimg any operation.
Another thing that just came to mind backing this approach is exception handling. Im sure you wouldn't want your constructorcto be throwing any kind of IOException in case it couldn't load the types from the file system.
Any initialization type of code should be done in the constructor, that way you know it will be called once and only once.
public class PluginProvider
{
IEnumerable<IPluginType> PluginTypes
{
get
{
return _pluginTypes;
}
}
public PluginProvider()
{
InitializePlugins();
}
}
What you are doing there is called lazy initialization. You are postponing doing a potentially costly operation until the very moment its output is needed.
Now, this is not an absolute rule. If your InitializePlugins method takes a long time to complete and it might impact user experience, then you can consider moving it into a public method or even making it asynchronous and call it outside of the property: at app startup or whenever you find a good moment to call a long-lasting operation.
Otherwise, if it's a short lived one-time thing it can stay there. As I said, not an absolute rule. Generally these are some guidelines for whatever applies to a particular case.
I have a form that has a button which creates a new object and calls it's start() method.
The program works fine, however, I now want to create a stop button. I obviously cannot call the object's stop() method as it is elsewhere, but, I just can't think of the correct way of changing my code.
As I write this, the best thing I can think of is to take the MyObject myo = new MyObject("test"); and place MyObject myo; at the top of the class, outside methods and then try to set it from within the class.
What would you do in this situation?
It's all dependent on scope.
If you want the form, at any time, to have visibility to that object, placing it as a private/protected member within the form's object is probably a good route. (make sure it's not null though.
class MyForm
{
private MyObject myobject;
private MyForm(){
// create the object
myobject = new MyObject;
}
private void Start_Click(){
myobject.start();
}
private void Stop_Click(){
myobject.stop();
}
}
If this object is constantly referenced, you could follow a singleton pattern.
If this is something you can re-create based on [an/the] argument(s) passed to the construct, you can re-create it every time it's needed.
That is is exactly what you are supposed to do. Its called creating a member variable.
But make sure you don't call myo.stop() when myo is null!
You are correct. You have to store the object reference some place so that you can call its "stop" method later.
I'm working on a GUI application, which relies heavily on Action<> delegates to customize behavior of our UI tools. I'm wondering if the way we are doing this has any potential issues, e.g. whether the implementation keeps references to captured variables, class instances that declare the delegates etc?
So let's say we have this class MapControl, which wraps a stateful GUI control. The map has different kinds of tools (Drawing, Selection, etc.), represented by ITool interface. You can set the tool with StartTool(), but you can only have one tool active at a time, so when another tool is set previous one is stopped using StopTool(). When tool is stopped, a caller-specified callback delegate is executed.
public class MapControl
{
ITool _currentTool;
Action<IResult> _onComplete;
public void StartTool(ToolEnum tool, Action<IResult> onComplete) {
//If tool is active, stop it first
if (_currentTool != null) StopTool();
_onComplete = onComplete;
//Creates a tool class, etc.
_currentTool = CreateTool(tool) as ITool;
}
public void StopTool() {
//Execute callback delegate
IResult result = _currentTool.GetResult();
if (_onComplete != null)
_onComplete(result);
//Nix the references to callback and tool
_onComplete = null;
_currentTool = null;
}
}
In the application's ViewModel class we set some tool like this:
class ViewModel
{
private MapControl _mapControl = new MapControl();
public void SetSomeTool()
{
//These variables will be captured in the closure
var someClassResource = this.SomeClassResource;
var someLocalResource = new object();
//Start tool, specify callback delegate as lambda
_mapControl.StartTool(ToolEnum.SelectTool, (IResult result) => {
//Do something with result and the captured variables
someClassResource.DoSomething(result, someLocalResource);
});
}
}
In our case the ViewModel class is attached to the main window of a WPF application, and there can only be one instance of ViewModel during the application lifetime. Would it change anything if this weren't the case, and the classes which declare the delegates would be more transient?
My question is, am I disposing of the callback delegates correctly? Are there any scenarios, where this can cause memory bloat by holding on to references it shouldn't?
More generally, what's the safe and correct way of disposing anonymous delegates?
IMHO, it is ok and you are not holding on to any references you don't need. With clearing the references in StopTool you no longer hold them.
You are doing fine with removing the Reference to methods that way.
One more thing you asked:
My question is, am I disposing of the callback delegates correctly?
You don't dispose methods (or pointers to methods for that matter), only classes.
I think a more proper way would be:
_onComplete = (Action<IResult>)Delegate.Remove(null, _onComplete);
If you want to make sure you are disposing correctly of all unused objects, I'd suggest you use tools like the CLR Profiler so that you can have a complete view of how your application is allocating/freeing memory.
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. :)