Определение локальной переменной const vs Class 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
}
}
Ответы
Ответ 1
При перемещении константы в класс нет увеличения производительности. CLR достаточно умен, чтобы распознавать константы как постоянные, так как производительность равна двум. То, что на самом деле происходит, когда вы компилируете IL, заключается в том, что значения констант жестко закодированы в программу компилятором как литералы.
Другими словами, константа не является ссылочной ячейкой памяти. Это не похоже на переменную, она больше похожа на литерал. Константа - это буквальная синхронизация в нескольких местах вашего кода. Так что это зависит от вас - хотя это более быстрое программирование, чтобы ограничить область действия константы там, где она имеет значение.
Ответ 2
Зависит от того, хотите ли вы использовать его во всем классе. Верхнее объявление будет использоваться во всем классе, тогда как другое будет доступно только в MyMethod
. Вы не получите никакого повышения производительности, сделав это в любом случае.
Ответ 3
Вот небольшой тест, который я сделал для оценки сценариев;
Код:
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);
}
}
}
}
Результаты трех итераций:
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.
Запустите тот же код из вашей системы и сообщите нам результат.
Ответ 4
Я бы поставил его в самом методе. Я не поклонник переменных, которые висят вокруг, когда им не нужно быть там.
Ответ 5
Я пытаюсь определить константы/переменные в самой минимальной области, в которой они мне нужны. В этом случае, если вы используете его только в пределах MyMethod
, оставьте его там.
Это делает более понятным тогда, когда применяется константа/переменная, а также позволяет вам проверять (даже если это проверка компиляции), если константа ссылается на другие места.
Исключение из этого может быть чем-то, что является "дорогим" (по времени) для создания/вычисления, поэтому я мог бы хотеть, чтобы это определяло экземпляр или статическое поле, поэтому мне нужно только вычислить его один раз.
Ответ 6
Зависит от того, где вы хотите его использовать, если вы собираетесь использовать другие методы, определите его в классе, если вы собираетесь использовать его только в одном методе, определите его в методе, который вы собираетесь использовать: )