web-dev-qa-db-ja.com

変数を宣言する場所

クラスのメソッドにforループがあることを考慮してください。インクリメントされた変数をmember of the classとして宣言する必要がありますか、それともin the methodとして宣言する必要がありますか(またはforループで直接)使用しますか?メソッド内で宣言する方が簡単でわかりやすいように見えますが、クラスの先頭で宣言すると、より制御しやすくなりますか?宣言するようなものint var_used_for_loop_in_method_x。プログラミングの実践とは何ですか?

特にforループを求めているわけではないことに注意してください。ほとんどの変数をクラスメンバーとしてできるだけ配置するかどうかを尋ねています。

3

経験則:変数は常に、それらが必要とされるスコープ内に-または可能な限り近くにある必要があります。別の言い方をすれば、変数は、意味があり実際に役立つコンテキスト内で囲む必要があります。

ほとんどの場合、forステートメントとともにインクリメントする変数を宣言する必要があります。ループの発生回数やループが中断された時点を知る必要があるため、階層で少し上位に宣言する場合があります。

ほぼすべてのシナリオで、ループ増分変数をクラスフィールドとして宣言することはお勧めできません。それはあなたにどんな種類の追加の「コントロール」も与えません。どちらかといえば、それはあなたのクラスを汚染するだけであり、部外者の視点から理解することを難しくします。さらに、誤って複数のループで使用すると、コードが壊れる可能性さえあります。

UPDATE:

後者については、以下のコメントでkeshlamが非常によく説明しているように、スコープを小さくすると、予期しない場所で変数が変更されるリスクが最小限に抑えられます。さらに、彼がさらに説明するように、スコープ外に出ると、変数は使用済みメモリを安全に解放できます。最近のほとんどの言語では、自動的にそれが行われます(マイレージは異なる場合があります)。

また、クラスレベルの変数がどのような目的に役立つかを尋ねたので、次に c# の2つの例を示します。

プロパティバックエンド

これはおそらく最も人気のあるユースケースです。

public class ConnectionHolder
{
    // ...

    IDbConnection _connection;

    public IDbConnection Connection
    {
        get { return _connection; }
    }

    // ...
}

インスタンス状態情報のホルダー

ここでは、上記の例のプロパティにファクトリにアクセスし、IDbConnectionのインスタンスを生成します。 _connectionAccessedブール変数は、接続を取得する試みがすでに行われたかどうかを示すフラグとして機能します。

public class ConnectionHolder
{
    // ...

    bool _connectionAccessed = false;
    IDbConnection _connection;

    public IDbConnection Connection
    {
        get
        {
            if (!_connectionAccessed)
            {
                _connectionAccessed = true;
                _connection = ConnectionFactory.Create();
            }

            return _connection;
        }
    }

    // ...
}

上記の2つの例でわかるように、変数を完全なクラススコープ内で宣言することは完全に理にかなっています。

この情報がお役に立てば幸いです。

42
Crono