2010-01-26 4 views
2

У меня есть следующая ситуация. В моем приложении есть очень распространенный класс, который содержит статическое поле readonly под названием «BinDirectory», которое содержит путь к каталогу bin. Другие поля этого класса, которые также являются статическими для чтения, используют это значение как базу для их значения. В текущей версии BinDirectory инициализируется для хранения каталога, в котором выполняется код (т. Е. Assembly.GetExecutingAssembly(). CodeBase). Я хочу расширить этот класс, чтобы инициализировать BinDirectory, чтобы удерживать «TargetDir» из контекста установщика, когда он запускается из моего установщика приложений. Я могу изменить BinDirectory просто статическим, но я не хочу, поскольку он заставит меня сделать много изменений в классе, который распространен в моем приложении. Может ли кто-нибудь предложить элегантное решение этой проблемы?Что касается C# Статические члены Readonly

ответ

3

Это то, что AppConfigs для. В разделе AppSettings добавьте новый ключ под названием BinDirectory. Вы можете повторно написать свой класс, как:

public static string BinDirectory 
{ 
    get 
    { 
     return ConfigurationManager.AppSettings["BinDirectory"]; 
    } 
} 

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

+0

Я думаю, что вы пропустили какую-то скобку '()' или 'get' там – Codesleuth

+0

Но могу ли я изменить AppSetting во время выполнения? Если да, то это решение для меня. – Ikaso

+0

лучший ответ здесь и да, вы можете изменить настройки приложения во время выполнения. – JonH

5

Сделать это свойство только с «получить» аксессор:

public static string BinDirectory 
{ 
    get { return _initialisedBinDirectory; } 
} 

Затем в статическом коде конструктора инициализации приватных переменный, как вам нужно.

EDIT

Задержка нагрузки (в соответствии с комментарием):

public static string BinDirectory 
{ 
    get 
    { 
     if (_initialisedBinDirectory == null) 
      // load the variable when needed 
     else 
      return _initialisedBinDirectory; 
    } 
} 

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

+0

Это не сработает, так как статический конструктор будет работать, когда кто-то сначала начнет использовать мой класс, который может произойти до того, как я назову BinDirectory. – Ikaso

+0

Я думал о решении для генерации кода или, может быть, другом элегантном стиле. – Ikaso

+0

Я не понимаю вашего комментария о проблеме с этим подходом. –

0

Похоже, вы не можете изменять статическое поле readonly просто статическим, потому что это заставит вас изменить инициализацию всех других статических полей readonly в вашем классе.

Если это верно, к сожалению, вы не можете многое сделать, но потратьте время, чтобы внести изменения. Позволяя установить поле BinDirectory во время выполнения, вы принципиально меняете последовательность инициализации полей. Ваш код нужно будет адаптировать.

Я думаю, что самый простой способ - преобразовать в использование статических свойств readonly, которые вычисляют значение «на лету».

Например:

public class Values { 
    public static string BinDir; 
    public static string OtherDir { 
    get { return Path.Combine(BinDir,@"Some\Other\Path"); } 
    } 
} 
+0

Возможно, вы захотите «кэшировать» результат Path.Combine в поле. Измените BinDir на свойство, а также дайте ему операцию частного набора. – Zyphrax

Смежные вопросы