web-dev-qa-db-ja.com

ローカル変数constとクラスconstの定義

メソッドでのみ必要の定数を使用している場合、constをメソッドスコープ内で宣言するのが最善ですか、それともクラススコープ内で宣言するのが最善ですか?メソッドでそれを宣言するより良いパフォーマンスはありますか?それが本当なら、値を変更して再コンパイルしやすくするために、クラススコープ(ファイルの先頭)でそれらを定義する方が標準的だと思います。

public class Bob
{
   private const int SomeConst = 100; // declare it here?
   public void MyMethod()
   {
      const int SomeConst = 100; // or declare it here?
      // Do soemthing with SomeConst
   }
}
47
Stealth Rabbi

定数をクラスに移動しても、パフォーマンスは向上しません。 CLRは、定数を定数として認識するのに十分スマートであるため、パフォーマンスに関する限り、2つは同じです。 ILにコンパイルすると実際に発生するのは、定数の値がコンパイラーによってリテラル値としてプログラムにハードコードされていることです。

つまり、定数は参照されるメモリ位置ではありません。それは変数のようなものではなく、リテラルのようなものです。定数は、コード内の複数の場所で同期されるリテラルです。したがって、定数の範囲を関連する場所に制限するのは優れたプログラミングですが、それはあなた次第です。

47
jnm2

クラス全体で使用するかどうかによって異なります。最上位の宣言はクラス全体で使用できますが、他の宣言はMyMethodでのみ使用できます。どちらの方法でも、パフォーマンスが向上することはありません。

9
Neil Knight

これは、シナリオを評価するために行った小さなベンチマークです。

コード:

using System;
using System.Diagnostics;

namespace TestVariableScopePerformance
{
    class Program
    {
        static void Main(string[] args)
        {
            TestClass tc = new TestClass();
            Stopwatch sw = new Stopwatch();

            sw.Start();
            tc.MethodGlobal();
            sw.Stop();

            Console.WriteLine("Elapsed for MethodGlobal = {0} Minutes {1} Seconds {2} MilliSeconds", sw.Elapsed.Minutes, sw.Elapsed.Seconds, sw.Elapsed.Milliseconds);
            sw.Reset();

            sw.Start();
            tc.MethodLocal();
            sw.Stop();

            Console.WriteLine("Elapsed for MethodLocal = {0} Minutes {1} Seconds {2} MilliSeconds", sw.Elapsed.Minutes, sw.Elapsed.Seconds, sw.Elapsed.Milliseconds);

            Console.WriteLine("Press any key to continue...");
            Console.ReadKey();
        }


    }

    class TestClass
    {
        const int Const1 = 100;

        internal void MethodGlobal()
        {
            double temp = 0d;
            for (int i = 0; i < int.MaxValue; i++)
            {
                temp = (i * Const1);
            }
        }

        internal void MethodLocal()
        {
            const int Const2 = 100;
            double temp = 0d;
            for (int i = 0; i < int.MaxValue; i++)
            {
                temp = (i * Const2);
            }
        }
    }
}

3回の反復の結果:

Elapsed for MethodGlobal = 0 Minutes 1 Seconds 285 MilliSeconds
Elapsed for MethodLocal = 0 Minutes 1 Seconds 1 MilliSeconds
Press any key to continue...

Elapsed for MethodGlobal = 0 Minutes 1 Seconds 39 MilliSeconds
Elapsed for MethodLocal = 0 Minutes 1 Seconds 274 MilliSeconds
Press any key to continue...

Elapsed for MethodGlobal = 0 Minutes 1 Seconds 305 MilliSeconds
Elapsed for MethodLocal = 0 Minutes 1 Seconds 31 MilliSeconds
Press any key to continue...

観察は@ jnm2の答えを結論付けていると思います。

システムから同じコードを実行して、結果をお知らせください。

7
user474407

私はそれをメソッド自体に入れます。私は、変数が存在する必要がないときにスコープ内でぶらぶらする変数のファンではありません。

3
jaltiere

私は定数/変数を必要とする最小限のスコープでのみ定義しようとしています。この場合、MyMethod内でのみ使用している場合は、そのままにしておきます。

定数/変数が適用される場所がより明確になり、定数が他の場所で参照されているかどうかをチェックする必要がなくなります(コンパイルチェックの場合でも)。

これの例外は、作成/計算するのに「費用がかかる」(時間的に)ものである可能性があるため、インスタンスまたは静的フィールドを定義して、1回だけ計算する必要がある場合があります。

3
Clinton

どこで使用するかによって異なります。他のメソッドで使用する場合はクラスで定義し、1つのメソッドでのみ使用する場合は、使用するメソッドで定義します:)

1
Aviatrix