2009-11-12 1 views
81

У меня есть разные константы, которые моя программа использует ... string, int, double, и т. Д. Каков наилучший способ их хранения? Я не думаю, что хочу Enum, потому что данные не все одного типа, и я хочу вручную установить каждое значение. Должен ли я просто хранить их в пустом классе? Или есть лучший способ?Каков наилучший способ хранения группы констант, которые использует моя программа?

+15

Любой способ, которым вы этого хотите - так вам это нужно. –

ответ

107

Возможно, вы могли бы иметь их в статическом классе со статическими свойствами только для чтения.

public static class Constants 
{ 
    public static string SomeConstant { get { return "Some value"; } } 
} 
+1

grrr .. 40 секунд быстрее на ничью :) –

+21

+1, но даже лучше, если вы можете вытащить их из файла ресурсов для локализации. –

+16

Кажется немногословным - почему бы не статические строки только для чтения? – emptyset

23

ИМО, используя класс, полный констант, отлично подходит для констант. Если они будут периодически меняться, я рекомендую использовать AppSettings в вашем config и классе ConfigurationManager.

Когда у меня есть «константы», которые фактически втянуты из AppSettings или аналогичные, я все равно всегда буду иметь класс «константы», который переносит чтение из диспетчера конфигурации. Всегда лучше иметь вместо того, чтобы прибегать непосредственно к ConfigurationManager.AppSettings["SomeModule/Setting"] в любом месте, которое хочет потреблять указанное значение настройки.

Бонусные баллы для этой установки, так как SomeModule, вероятно, будет вложенным классом внутри файла Constants, вы можете легко использовать инъекцию зависимостей, чтобы ввести SomeModule непосредственно в классы, которые зависят от него. Вы также можете извлечь интерфейс поверх SomeModule, а затем создать свой код для ISomeModuleConfiguration в своем коде потребления, это позволит вам отделить зависимость от файлов Constants и даже потенциально упростить тестирование, особенно если эти параметры исходят из AppSettings, и вы меняете их с помощью конфигурационных преобразований, потому что настройки зависят от среды.

+1

Просто добавьте к этому: причина в том, что при построении константы, используемые из других сборок, не обновляются. Это означает, что если у вас есть AssemblyA и AssemblyB и B использует константу из A, значение копируется, а не ссылается, поэтому повторное построение A не будет обновлять B. Это может привести к странным ошибкам. –

+1

@CamiloMartin много способов справиться с этим, ваши «константы» могут просто статические readonlys, чтобы избежать этого, или, как я сказал, если они меняются более одного раза в голубой луне, чтобы использовать ConfigurationManager. –

+0

Да, я просто сказал, что дело не только в том, что это соглашение, что вы должны использовать статическую readonly, а потому, что на самом деле это может быть источником путаницы. Кроме того, альтернативой ConfigurationManager являются файлы ресурсов - вам просто нужно добавить еще один файл ресурсов с кодом языка в имени и ваш код будет немедленно локализован. –

17

То, что я хочу сделать, это следующее (но не забудьте прочитать до конца, чтобы использовать правильный тип констант):

internal static class ColumnKeys 
{ 
    internal const string Date = "Date"; 
    internal const string Value = "Value"; 
    ... 
} 

Read this знать, почему const не может быть что ты хочешь. Возможные типа констант является:

  • const поля. Не используйте поперек сборок (public или protected), если значение может в будущем изменить, поскольку значение будет жестко запрограммировано во время компиляции в этих других сборках. Если вы измените значение, старое значение будет использоваться другими сборками, пока они не будут повторно скомпилированы.
  • static readonly поля
  • static недвижимость без set
+1

Почему readonly, если используется в нескольких сборках? –

+0

Почему статическая readonly лучше работает с несколькими сборками, чем const? –

+13

Значения констант копируются из исходной сборки в скомпилированный код. Это означает, что если вам нужно изменить значение const, все зависимые сборки ДОЛЖНЫ перекомпилироваться в новой версии. Безопаснее и удобнее использовать статические readonly. – cfeduke

4

Пустой статический класс подходит. Подумайте о том, как использовать несколько классов, чтобы у вас были хорошие группы связанных констант, а не один гигантский файл Globals.cs.

Кроме того, для некоторых ИНТ констант, рассмотрим обозначение:

[Flags] 
enum Foo 
{ 
} 

Как это позволяет treating the values like flags.

+0

«Рассмотрите возможность использования нескольких классов, чтобы вы получили хорошие группы связанных констант, а не один гигантский файл Globals.cs». Я считаю, что это лучшая рекомендация, разве вокруг не существует некоторых шаблонов дизайна? Я не знаю по имени, не так ли? –

1

Да, для хранения констант будет просто отлично, за исключением констант, связанных с конкретными типами.

+0

это именно то, что я пытаюсь сделать. я хочу, чтобы они появились как члены класса, для которого они предназначены. но я не хочу добавлять их в классы, потому что константы меняются в зависимости от компании, за которую я работаю. Я еще ничего не нашел о константах или свойствах расширения. но я могу отказаться от этой идеи, потому что я не хочу, чтобы они отображались как члены, когда я сериализую эти классы. – symbiont

3

Еще одно голосование за использование web.config или app.config. Конфигурационные файлы - хорошее место для констант, таких как строки подключения и т. Д. Я предпочитаю не смотреть на источник, чтобы просматривать или изменять эти типы вещей. Статический класс, который читает эти константы из файла .config, может быть хорошим компромиссом, так как он позволит вашему приложению получать доступ к этим ресурсам, как если бы они были определены в коде, но при этом все же дает вам гибкость в их легко просматриваемом/редактируемом пространство.

+2

Строка соединения не является константой, это параметр. Может быть, OP * действительно * означает настройки тоже, а не константы, но я не вижу никаких доказательств. –

+0

Прошу отличить. Строковые литералы по определению являются константами. Изменение строки в файле конфигурации примерно эквивалентно изменению ее в коде и перекомпиляции; * что * сделать это не постоянным? Я так не думаю. –

+2

@ Давид - Неправда. Компилятор не заботится о том, какое значение у вас есть в вашем файле конфигурации - это читается во время выполнения. –

8

Это лучший способ ИМО. Нет необходимости в свойствах, или только для чтения:

public static class Constants 
{ 
    public const string SomeConstant = "Some value"; 
} 
+8

Если вы собираетесь использовать const, выставляйте только как внутренние. Не создавайте const public (даже если вы считаете, что ваши сборки не будут использоваться вне вашей организации). Также свойства дают вам гибкость в программировании для будущего расширения без необходимости переопределять ваш интерфейс. – cfeduke

0

Если эти константы являются ссылки обслуживания или переключатели, которые влияют на поведение приложения я бы установить их в качестве пользовательских настроек приложений. Таким образом, если их нужно изменить, вам не нужно перекомпилировать, и вы все равно можете ссылаться на них через класс статических свойств.

Properties.Settings.Default.ServiceRef 
-1

Я предлагаю статический класс со статическим readonly. Пожалуйста, найдите фрагмент кода ниже:

public static class CachedKeysManager 
    { 
     public static readonly string DistributorList = "distributorList"; 
    }