Reputation: 4852
I occasionally find myself in a situation where I have a variable that will only ever be used by one method in a class. Currently I use an instance variable, but it seems like bad design to have this variable visible to the rest of the class. Example just to illustrate a situation where I want this:
private Window _Window;
private void Show()
{
if (_Window == null)
{
_Window = new Window();
_Window.Closed += delegate { _Window = null; };
_Window.Show();
}
_Window.BringIntoView();
}
The instance variable only exists to prevent more than one window being created at a time, so there's no reason for the rest of the class to know about it. I'm reminded of C++'s ability to define static variables within a function.
Is there any way to achieve something like this is C#? Or am I stuck with the decision of choosing between bad design and bad encapsulation? (Assuming that this method truly doesn't warrant a class of its own.)
Upvotes: 4
Views: 488
Reputation: 8873
The only approach known to me is worse than the clutter you are trying to avoid.
// Constructor
public MyClass()
{
{
// _Window is private to this closure
Window _Window;
Show = () =>
{
if (_Window == null)
{
_Window = new Window();
_Window.Closed += delegate { _Window = null; };
_Window.Show();
}
_Window.BringIntoView();
};
}
}
// Replaces Show method
private Action Show;
Then use Show.Invoke() instead of Show(). There are however places where this approach is better: http://www.headspring.com/patrick/public-private-super-private/. However, in my opinion, method private should be in C# / Java.
Upvotes: 1
Reputation: 112299
An option would be to let the window class itself keep a static reference to an instance of itself. You would also expose a static method Display()
in the window class, letting the window class handle the creation and disposal of instances. Basically you would have to move your code into your windows's class.
private static DisplayWindow _window;
public static void Display()
{
if (_window == null)
{
_window = new DisplayWindow();
_window.Closed += delegate { _window = null; };
_window.Show();
}
_window.BringIntoView();
}
In another class
DisplayWindow.Display(); // No variable required here!
If you want to disallow the "wild" creation of windows of this type, make the constructor of the window private
private DisplayWindow()
{
}
This forces other classes to call Display()
if they want to open this window.
Upvotes: 0
Reputation: 1500015
Is there any way to achieve something like this is C#?
No.
Or am I stuck with the decision of choosing between bad design and bad encapsulation? (Assuming that this method truly doesn't warrant a class of its own.)
Well, I'm not sure you're actually stuck with either of those. It sounds like this is part of the state of the object, even if none of the other methods need to refer to that aspect of its state. Would it be logically wrong for other code within the same class to refer to this aspect of state? If so, why?
(Admittedly I've occasionally wished for the ability to declare a field "within" a property declaration, forcing the rest of the class to access the state via the property...)
Upvotes: 4
Reputation: 564363
Is there any way to achieve something like this is C#?
No, unfortunately, C# does not have the ability to define a class level variable scoped to a method.
As a side note, Visual Basic does allow this via the Static modifier. This causes the compiler to create a (decorated) class level variable, but the language will only allow it to be used within the Sub or Function in which its defined. Other languages will see it as a member variable, however.
Upvotes: 1