Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I have some confusion regarding the use of static variables/references in a class. It feels like I may not have entirely figured out the implications of keeping something static.

When I say a variable is public static, is it one instance of the variable per class or one instance per assembly?

For example, I have a user control (say, for a WPF app). This user control has a public static variable that coordinates various things within the control. If there is a form in a client application that uses this user control, with multiple instances of this control per form, how many instances of the public static variable are created? (My guess is only one, and it is modified by every control).

Now, I actually need each instance of the control to have one such variable, not one variable across all the instances of the control in that single form.

Does using a singleton pattern, with a "lock" keyword solve this issue i.e will it create one variable per instance of the user control? If not, what issue does the singleton pattern solve? What are the options in solving this design problem?

(Note: I have resorted to creating an internal non static global variable and passing it around carefully, instead of going the static route and its working fine. I am looking to see if there is another option.)

(Please bear with me if the question sounds very naive or unresearched, I did read a bit before posting, but seem stuck on finding an answer that explains it very clearly to me.)

share|improve this question
1  
msdn on the static modifier –  Mike L. Jan 6 '13 at 18:57

2 Answers 2

I think you're doing this too convoluted for yourself. I'd use some kind of a presenter/controller class in the application that the user control will have a reference to. That way a state is maintained between all user controls if they're using the same presenter object.

There is no need for singletons here, the application itself can hold the state for each presenter/controller, unless you have a more compelling reason to why you'd use singleton.


EDIT:

So from the comments I've gathered the OP wants a collaborator object to exist once per instance. This means that for each instance there is one object and is not what singleton is about (or anything static really).

You can just as well create a collaborator like this:

public class Collaborator {
    // members and methods
}

And for your custom User control you can create it in the constructor, though you also need to call the base class's constructor as well like this:

private Collaborator _collaborator;

// Constructor in your CustomUserControl
public CustomUserControl() : base() {
    _collaborator = new Collaborator;
}

Whenever the code is creating a child user control you can let it pass the collaborator through the constructor to the child user control. Say there is an event that creates child user controls:

void OnButtonMakeSubClick(object sender, RoutedEventArgs e)
{
    _childControl = new ChildControl(_collaborator);
}

And in your child control you add the following constructor:

private Collaborator _collaborator;

public ChildControl(Collaborator collaborator) : base() {
    _collaborator = collaborator;
}

Hope this hints out what you want.

share|improve this answer
    
a. I do NOT need the user controls to know of each other's presence, let alone maintain state across them. b. I only get to write the user control, as a third party of sorts, I do not have any control over how the application chooses to use my control. c. I do need to coordinate a few things across the child components of my own control, at a per instance level. –  Harsha Jan 6 '13 at 18:57
    
@Harsha: Then why do you need a singleton? That pattern is all about maintaining the same monadic state throughout the application. Make some plain old regular private fields instead. –  Spoike Jan 6 '13 at 18:59
    
The coordinator needs to be single per instance of the user control and available in all the child controls of the user control), which suggested making the coordinator static for easy accessibility (passing references around requires careful dereferencing). Which led me to my question. –  Harsha Jan 6 '13 at 19:03
    
@Harsha: I'm translating that to "for each instance of the user control there should be one coordinator that also should be available in all of the seperate user control's child controls". You don't need singleton for this. –  Spoike Jan 6 '13 at 21:30
3  
@Spoike - "You don't need singleton for this." - I am thinking a bigger gun ... that as "A singleton is wrong for this" –  mattnz Jan 7 '13 at 1:23

Completely ignoring any temptation to guess at the specifics of what you're trying to accomplish with your controls, or why, let me take a quick stab at answering your basic questions.

Up front; from your description, I think it sounds like your best option is just to have an instance field, not a static one, and not a singleton. You said "I actually need each instance of the control to have one such variable, not one variable across all the instances of the control in that single form." That is kind of a loose definition of an instance variable. Does it even really need to be public?

Actually, I would make it an instance property, because chances are pretty good that sooner or later you'll want to raise some event when the thing changes, or do something else that will end up making a public field feel like an unfortunate decision in retrospect. Hindsight is always 20/20. Or at least 20/30 or so. But in this case, a little foresight says that using a simple automatic property is cheap insurance:

public SomeDataType WidgetSettings{ get; set; }

So; there is only one instance of a static field/variable for the entire assembly. Every instance of the class containing that public static variable has a reference to the very same object in memory. So yes, all of your control instances are accessing the very same object/memory.

Any time you see "static" and "public" together in the same variable declaration line, it should be reason to pause and think. The thing is, if the variable is something like a string, or a numeric type, or a simple collection, you will have to use synchronization code everyplace that you access that field from. On the other hand, if it's a reference to a class with static getters and setters for various attributes, then you can put that synchronization code in the getters and setters, and you can test that class and its attributes in isolation (as a unit) and know that it works properly. I don't know if I expressed that as well as I meant to... But honestly, if you can what you need to do using instance variables and avoiding the whole thread-safety issue altogether, then do that instead.

If you have a static variable, it is absolutely for certain not thread-safe. At all. Maybe you're thinking that you're doing a Winforms app and all of the UI stuff executes on a single thread (because Winforms is not thread-safe), which is true enough if you follow the rules, except that we're all creative about using timers and background workers and such to loosen things up. So it is still possible for strange things to happen. So in the worst case, not only are all of your control instances accessing and updating the same variable, they might be trampling all over each other in the process.

If you're messing with WPF, then the UI library is thread-safe and the potential pitfalls of multithreading combined with static fields apply.

If the data that the variable points at is a type that requires more than one instruction to write completely, then it is only a matter of time before one control instance writes only half of a new value before the next control instance reads that field and gets a value composed of half of one write and half of a different write. I think the proper technical term for that situation is something along the lines of "fubar." Of course the thread that reads that mangled variable may well try to write back to it before it gets swapped out by the thread scheduler and the original thread gets another go, replacing the first thread's half-value with its own half-value before the first thread even gets a chance to write the second half of its value. This is likely to end in tears, or baldness, or more likely both tears and baldness.

Finally, the singleton has all the same potential thread-safety issues as the static field, because the whole notion of a singleton is that you grab your instance from a factory method, which serves the same single instance up to everybody who asks. So everybody who asks is, by definition, accessing the very same object.

In this case, my gut tells me that "singleton" is a code word for "fancy static field, which requires a lot more code and a lot more testing, and still isn't thread-safe unless you write error-prone and performance-robbing synchronization code to go with it."

When a code word has a definition that long, it's worth seriously looking at a different approach.

For what it's worth. :-) Without more detail it would be awfully difficult to provide any answers that relate directly to your question. What type of object is this static field pointing at? Is it a collection? Is it some kind of settings or configuration class with multiple properties? Is it an object that communicates with other parts of the system (events) in response to different signals you send it? Etc.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.