0

これが無効な慣行になるかどうかはわかりません。または良い習慣。私が途方に暮れている理由は、ローカル変数の代わりにプロパティを利用するべきですか?

私の理由と目標; ローカル ディスク ドライブの非常に基本的な検出でした。

私が指摘したいいくつかのこと:

  • boolean valueこのクラスを呼び出してドライブ パスを返すことができるようにしたいので、a を選択しませんでした。その名前はメソッドから取得されます。Path Combined一部の派生クラスに含めることができます。

私の例:

    public class Drive
    {
        // Variable:
        public string nameOfDrive;

        public Drive()
        {
            // Call Method.
            DriveName();
        }

        public string DriveName()
        {
            DriveInfo [] drives = DriveInfo.GetDrives();
            foreach (DriveInfo d in drives)
            {
                // Verify Valid 'C:' is Present.
                if (d.Name == @"C:")
                {
                    // Set Name:
                    nameOfDrive = d.Name;
                    // Return Result.
                    return d.Name;
                }
            }
            // Exception:
            throw new Exception("Unable to locate the C: Drive... Please map the correct drive.");
        }

    }
    /*
     * The above method and class contains a verification
     * for the 'C:' Drive.  Once the items are validated;
     * it will create a return variable for the 'C:'.  
     * Otherwise it will throw an Exception.
    */

今、これは私がより良い練習であるかわからないところです。の代わりにプロパティを使用する必要がありpublic string nameOfDriveます。それとも、私は本当に離れていますか?これは、他のクラスで利用できる値を返すための最良の方法ではありませんか? それとも、メンバー変数を直接参照するのは悪い習慣ですか?

2 番目の例:

    public class Drive
    {
        private string nameOfDrive;
        public string NameOfDrive
        {
            get { return nameOfDrive; }
        }
        public Drive()
        {
            // Call Method.
            DriveName();
        }
        public string DriveName()
        {
            // Obtain Drive Information:
            DriveInfo [] drives = DriveInfo.GetDrives();
            foreach (DriveInfo d in drives)
            {
                // Verify Valid 'C:' is Present.
                if (d.Name == @"C:")
                {
                    // Set Name:
                    nameOfDrive = d.Name;
                    // Return Result.
                    return d.Name;
                }
            }
            // Exception:
            throw new Exception("Unable to locate the C: Drive... Please map the correct drive.");
        }
    }
    /*
     * The above method and class contains a verification
     * for the 'C:' Drive.  Once the items are validated;
     * it will create a return variable for the 'C:'.  
     * Otherwise it will throw an Exception.
    */

そうすれば、読み取り専用としてマークされ、メソッドから適切な値を読み取ることが保証されますか?


アップデート:

回答ありがとうございます。しかし、なぜそれがより良い練習なのでしょうか?

  • セキュリティに有利ですか?
  • すっきりしただけ?
  • より柔軟

それがより良い解決策である理由; それが私が理解しようとしているものです。

4

5 に答える 5

4

Lazyクラスを使用してこれを行うことができます。これは、計算に時間がかかる可能性のある値を遅延初期化するというこの正確な問題を解決するために特別に設計されています。オブジェクトに値の計算に使用されるメソッドを与えることができますLazy。最初に値が要求されると、関数を使用して値が生成され、後続のすべての呼び出しはその最初の値を返すだけです。また、スレッドセーフであるという利点もあります(関数は、生成される前に値を要求する人の数に関係なく、一度だけ呼び出され、計算されて返されるまで待機します)。

public class Drive
{
    private Lazy<string> nameOfDrive = new Lazy<string>(DriveName);

    public string NameOfDrive
    {
        get { return nameOfDrive.Value; }
    }

    private static string DriveName()
    {
        DriveInfo[] drives = DriveInfo.GetDrives();

        foreach (DriveInfo d in drives)
        {
            if (d.Name == @"C:")
                return d.Name;
        }

        throw new Exception("Unable to locate the C: Drive... Please map the correct drive.");
    }
}
于 2012-12-28T20:22:13.913 に答える
3

プライベート メンバー変数で読み取り専用プロパティを使用します。これにより、呼び出しコードを壊さずにドライブ文字を検索する方法を変更した場合でも、クラスを簡単に更新できます。

DriveNameメソッドが何かを返すのはなぜですか? 公に使用されていますか、それとも単にNameOfDriveプロパティに入力するために使用されていますか? クラス内でのみ使用する場合は、プライベートにして無効にします。

編集:考えてみると、これはドライブの存在をチェックするだけでなく、最初に文字をチェックする奇妙な方法のようにも思えます。ユーザーのドライブ文字を にする必要があるのはなぜC:ですか? ユーザーがマシンをセットアップする方法は重要ではありません。必要に応じてOS ドライブを使用できるようにするQ:必要があり、コードを壊してはなりません。

于 2012-12-28T19:44:16.210 に答える
2

ただし、それは必ずしも悪い習慣ではありませんが、良いことでもありません。

ほとんどの場合、フィールドは単純なデータ クラスがある場合に使用する必要があります (通常、実際のコードは関係なく、値を格納する方法のみ)。そのレベルの複雑さを超える場合は、通常、クラスでプロパティを使用する必要があります。いくつかの理由:

  1. 後でフィールドからプロパティに変換すると、依存関係が壊れ、クラスを使用するすべてのコードを再コンパイルする必要があります
  2. プロパティは、よりきめ細かく制御できます。ユースケースを一目見ただけで、ドライブ文字を自動的に入力してキャッシュし、デフォルトのセッターをプライベートにして読み取り専用にするゲッターが必要なようです
  3. プロパティは仮想にすることができます。これは、人々があなたのクラスを、あなたが最初に想像した以上に簡単に拡張できることを意味します。
于 2012-12-28T20:47:18.040 に答える
1

cdrive を抽出するためのクラス (または拡張機能) を作成します。必要に応じて、消費者にエラーをスローさせます。

汎用メソッドを作成することで、状況に応じてプロセスを再利用できるようになり、概念を固有のオブジェクトに分離するというオブジェクト指向の原則の使用に準拠します。

void Main()
{

  if (Drive.AcquireCDrive() == null)
      throw new Exception("Unable to locate the C: Drive... Please map the correct drive.");

}

public class Drive
{
    public static DriveInfo AcquireCDrive()
    {
       return DriveInfo.GetDrives()
                       .OfType<DriveInfo>()
                       .Where (drive => drive.IsReady)
                       .FirstOrDefault( drive => drive.Name.Contains(@"C:"));
    }
} 
于 2012-12-28T20:16:30.550 に答える
0

おそらく、読み取り専用プロパティを使用することをお勧めしますが、遅延ロードします。

以下に注意してください。メソッドをプライベートにし、コンストラクターでメソッドをDriveName()呼び出しませんでした。DriveName()

public class Drive
{
    private string nameOfDrive = null;

    public string NameOfDrive
    {
        get 
        {
            if (nameOfDrive == null)
                nameOfDrive = DriveName();
            return nameOfDrive; 
        }
    }

    public Drive()
    {    }

    private string DriveName()
    {
        DriveInfo[] drives = DriveInfo.GetDrives();

        foreach (DriveInfo d in drives)
        {
            if (d.Name == @"C:")            
                return d.Name;
        }

        throw new Exception("Unable to locate the C: Drive... Please map the correct drive.");
    }
}
于 2012-12-28T19:54:02.060 に答える