4

我偶尔会发现自己有一个变量,该变量只能被类中的一种方法使用。目前我使用一个实例变量,但让这个变量对类的其余部分可见似乎是糟糕的设计。示例只是为了说明我想要的情况:

private Window _Window;
private void Show()
{
    if (_Window == null)
    {
        _Window = new Window();
        _Window.Closed += delegate { _Window = null; };
        _Window.Show();
    }
    _Window.BringIntoView();
}

实例变量的存在只是为了防止一次创建多个窗口,因此类的其余部分没有理由知道它。我想起了 C++ 在函数中定义静态变量的能力。

有什么方法可以实现这样的C#吗?还是我坚持在糟糕的设计和糟糕的封装之间做出选择?(假设这个方法确实不能保证它自己的类。)

4

4 回答 4

4

有什么方法可以实现这样的C#吗?

不。

还是我坚持在糟糕的设计和糟糕的封装之间做出选择?(假设这个方法确实不能保证它自己的类。)

好吧,我不确定你是否真的被其中任何一个所困扰。听起来这是对象状态的一部分,即使其他方法都不需要引用其状态的那个方面。同一个类中的其他代码引用状态的这个方面在逻辑上是错误的吗?如果是这样,为什么?

(诚​​然,我偶尔希望能够在属性声明“内”声明一个字段,从而强制类的其余部分通过该属性访问状态......)

于 2012-08-29T16:40:27.077 回答
1

有什么方法可以实现这样的C#吗?

不,不幸的是,C# 没有能力定义作用域为方法的类级别变量。

附带说明一下,Visual Basic 确实通过Static 修饰符允许这样做。这会导致编译器创建一个(修饰的)类级变量,但语言只允许在定义它的 Sub 或 Function 中使用它。但是,其他语言会将其视为成员变量。

于 2012-08-29T16:40:03.447 回答
1

我知道的唯一方法比你试图避免的混乱更糟糕。

// 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;

然后使用 Show.Invoke() 而不是 Show()。然而,这种方法在某些地方更好:http ://www.headspring.com/patrick/public-private-super-private/ 。但是,在我看来,私有方法应该在 C#/Java 中。

于 2013-01-13T23:48:00.093 回答
0

一种选择是让窗口类本身保持对自身实例的静态引用。您还将Display()在窗口类中公开一个静态方法,让窗口类处理实例的创建和处置。基本上你必须将你的代码移动到你的windows类中。

private static DisplayWindow _window;

public static void Display()
{
    if (_window == null)
    {
        _window = new DisplayWindow();
        _window.Closed += delegate { _window = null; };
        _window.Show();
    }
    _window.BringIntoView();
}

在另一个班级

DisplayWindow.Display(); // No variable required here!

如果您想禁止这种类型的窗口的“狂野”创建,请将窗口的构造函数设为私有

private DisplayWindow()
{
}

Display()如果他们想打开这个窗口,这会强制其他类调用。

于 2012-08-29T16:52:38.717 回答