4

クラス内の 1 つのメソッドによってのみ使用される変数がある状況に陥ることがあります。現在、私はインスタンス変数を使用していますが、この変数をクラスの残りの部分から見えるようにするのは悪い設計のようです。これが必要な状況を説明するための例:

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() の代わりに Show.Invoke() を使用します。ただし、このアプローチの方が優れている場所もあります: http://www.headspring.com/patrick/public-private-super-private/。ただし、私の意見では、メソッド private は C#/Java にある必要があります。

于 2013-01-13T23:48:00.093 に答える
0

オプションは、ウィンドウ クラス自体がそれ自体のインスタンスへの静的参照を保持できるようにすることです。また、ウィンドウ クラスで静的メソッドDisplay()を公開し、ウィンドウ クラスがインスタンスの作成と破棄を処理できるようにします。基本的に、コードをウィンドウのクラスに移動する必要があります。

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 に答える