Как мне сохранить данные без глобальных переменных? - PullRequest
8 голосов
/ 22 мая 2009

Я привык к языкам сценариев. PHP, Javascript и т. Д., И я написал несколько относительно простых приложений на Java и C #. Это вопрос, на который мне неоднократно требовался ответ, и я думаю, что я не единственный.

Допустим, я в Javascript.

У меня есть функция A (), вызываемая графическим интерфейсом, которая извлекает некоторое значение.

Функция B (), также вызываемая графическим интерфейсом, требует это значение, но функция B () будет вызываться произвольное число раз, произвольная продолжительность времени после A ().

Я не хочу, чтобы A () каждый раз пересчитывала значение.

Пример - учетные данные для входа. A () запрашивает имя пользователя, а B () использует это значение для добавления в журнал каждый раз, когда он вызывается.

Для этого я бы, вероятно, просто использовал глобальную переменную.

Теперь, C #. Нет глобальных переменных! Как я должен это сделать?

Edit: Наслаждайтесь ответами, но есть много комментариев "старайтесь не использовать глобалы". Что я понимаю, но я хотел бы услышать альтернативные шаблоны для этого требования.

Ответы [ 5 ]

5 голосов
/ 22 мая 2009

Это не очень хорошая практика, но если она вам действительно нужна, есть несколько способов:

  1. Веб-приложения. Вы можете поместить свою переменную в некоторый контекст, например, в сеанс или область приложения.
  2. Настольные приложения: вы можете создать объект и сохранить его как свойство класса, в котором всегда активен объект.
  3. Любое приложение: используйте открытое статическое свойство. Это видно всем.
4 голосов
/ 22 мая 2009

Во-первых, всегда спрашивайте себя, действительно ли вам нужно иметь глобальный, часто вы не будете. Но если вам действительно нужен один ...

Лучший способ сделать это - иметь статическое свойство для некоторого разумно названного класса, оно фактически становится вашей глобальной переменной

public class Credentials
{
  public static string Username {get;set;}
}

//...somewhere in your code

Credentials.Username = "MyUserName";

EDIT:

Несколько человек здесь сказали общее заявление о том, что глобальные переменные плохие, и я согласен с этим мнением, и кажется, что разработчики C # также согласны, поскольку они просто недоступны.

Однако нам следует рассмотреть причины, по которым глобальные переменные являются плохими, и они в основном считаются плохими, потому что вы нарушаете правила инкапсуляции. Статические данные, тем не менее, не обязательно плохие, хорошая вещь в статических данных заключается в том, что вы можете инкапсулировать их, мой пример, приведенный выше, является очень упрощенным примером того, что, вероятно, в сценарии реального мира вы включили бы свои статические данные в тот же класс, выполняет другую работу с учетными данными, например, класс Login или класс User, или что-то еще, что имеет смысл для вашего приложения.

1 голос
/ 22 мая 2009

Я бы сказал, что вам, вероятно, следует использовать Singleton Pattern .

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

Как всегда, пожалуйста, подумайте о внедрении любого вида глобализации в ваше приложение, но не бойтесь его использовать. Многие вещи действительно являются глобальными, например App.Settings, в которых нет ничего «плохого».

В этой статье на MSDN объясняется, как правильно создать синглтон в c #.

0 голосов
/ 22 мая 2009

Функция A будет частью класса (назовите ее C). Функция A может затем сохранить учетные данные для входа и предоставить функцию (или в C #, свойство) для получения учетных данных. Когда они требуются, вы можете просто использовать свойство, чтобы получить сохраненные учетные данные и передать их в функцию B (в другом классе).

class C
{
    public void functionA()
    {
         credentials = obtainCredentials;
    }

    private LogonCredentials _logonCredentials = null;

    public LogonCredentials logonCredentials
    {
        get { return _logonCredentials; }
    }
}

class D
{
    public void functionB(LogonCredentials credentials)
    {
       //do stuff
    }
}

///other stuff
///other function ...
    ...
    instanceC = C();
    instanceC.functionA();
    ///more stuff here
    instangeD = D();
    instanceD.functionB(instanceC.logonCredentials);
0 голосов
/ 22 мая 2009

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

Тем не менее, для вашей проблемы это звучит гораздо больше как проблема дизайна. C # очень ориентирован на объектно-ориентированный дизайн; Я подозреваю, что проблема, с которой вы столкнулись, связана с тем, что лучший OOD решит вашу проблему.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...