#c# #.net #c#-4.0
#c# #.net #c #-4.0
Вопрос:
В общедоступном классе у меня есть частный статический словарь. Поскольку словарь статичен, означает ли это, что он является общим для всех других экземпляров того же объекта (см. Пример ниже).
public class Tax
{
private static Dictionary<string, double> TaxBrakets = new Dictionary<string, double>(StringComparer.OrdinalIgnoreCase)
{
{ "Individual", 0.18 },
{ "Business", 0.20 },
{ "Other", 0.22 },
};
public string Type { get; set; }
public double ComputeTax(string type, double d)
{
return d * TaxBrakets[this.Type];
}
}
Допустимо ли использовать словарь таким образом (как статическую переменную)?
Комментарии:
1. Вам следует подумать о том, чтобы не использовать
string
в качестве своего типа. Может быть,enum
и массив были бы лучше, чемstring
и aDictionary
?2. И если это реальный код, вы должны использовать
decimal
, а неdouble
для валюты. У плавающих точек может быть странное поведение и такие числа, как17.9999999...
. Я уверен, что на этом сайте есть вопрос, который объясняет это 🙂
Ответ №1:
Ваша статическая переменная TaxBrakets
не связана с экземпляром. this.TaxBrakets
не будет компилироваться. Все вхождения TaxBrakets
будут ссылаться на один и тот же словарь. В общем, использование статических словарей вполне приемлемо. Хотя это конкретное использование кажется немного забавным, но мне нужно было бы увидеть больше кода, чтобы предложить какие-либо изменения.
Комментарии:
1. Область видимости будет разрешена для класса, а не для экземпляра, поэтому на самом деле будет компилироваться только
TaxBrackets
(но, как вы указали,this.TaxBrackets
не будет).
Ответ №2:
Да, статическая переменная существует только один раз во всей вашей программе, я думаю, она будет вести себя так, как вы ожидаете.
Является ли это правильным решением вашей бухгалтерской проблемы, является спорным, IANAA, но я понимаю, что налоговые скобки (примечание: правильное написание «скобок» имеет c
) приравнивают уровни дохода к предельным налоговым ставкам, знание типа объекта само по себе недостаточно для определения налоговой ставки.
Комментарии:
1. Существует только один раз для
AppDomain
, если быть точным.2. @CodeInChaos: Это верное утверждение, но я вряд ли думаю, что OP, вероятно, будет использовать несколько доменов приложения.
Ответ №3:
Да, этот статический элемент будет общим для всех экземпляров. (Visual Basic фактически делает это явным, используя Shared
ключевое слово для статических членов, а не static
.)
Вполне допустимо использовать словарь таким образом, с одной оговоркой: если ваш код многопоточный, вы должны убедиться, что доступ к статическому элементу потокобезопасен. (Конечно, это относится ко всем элементам, к которым можно обращаться одновременно, а не только к статике.)
Не имеет прямого отношения к вопросу, но вам, вероятно, следует использовать decimal
, а не double
для всего, что связано с денежными значениями или финансовыми расчетами.
Ответ №4:
Да, она будет общей, и да это должно быть нормально, это будет потокобезопасно, а также без обновления. Я бы просто добавил readonly
к объявлению:
private static readonly Dictionary<string, double> TaxBrakets = new Dictionary<string, double>(StringComparer.OrdinalIgnoreCase)
{
{ "Individual", 0.18 },
{ "Business", 0.20 },
{ "Other", 0.22 },
};
Ответ №5:
Статическое свойство на самом деле не является общим для экземпляров как таковых, но вы используете его правильно.
Ответ №6:
Да, static указывает, что это единственная переменная в пределах класса Tax.
Вам нужно будет получить к ней доступ следующим образом
return d * Tax.TaxBrackets[this.Type]
Комментарии:
1. Вам не нужно указывать имя класса, когда вы используете статический член внутри класса.
2.
Tax.
Префикс не нужен, статические члены могут быть найдены путем поиска по имени без ограничений при использовании внутри других членов того же класса (и потомков).3. Да, я знаю, что в этом нет необходимости, однако это помогает устранить некоторую путаницу, когда другие приходят для поддержки вашего кода и им нужно найти, что это за переменная. Особенно в таких вещах, как Java, где вы можете выполнять статический импорт, становится все труднее отслеживать, откуда был импортирован статический элемент. 🙂
Ответ №7:
ДА. На самом деле, если бы она не была скрыта private
, то она была бы доступна даже без какого-либо экземпляра.
Например:
public class X
{
public static String y = "abc";
}
// other code, even without instances of X alive:
Console.WriteLine(X.y);
Комментарии:
1. Даже будучи частной, она доступна без экземпляра, например, из внутренних классов экземпляров.
2. Совершенно верно. Я намеренно проигнорировал использование отражения, но пример внутреннего класса вылетел у меня из головы.