C # статический класс и вопрос о членах данных

Я не уверен, как реализовать задуманное с помощью C # .Net 3.5. У меня есть статический класс Common, который содержит общие методы. Один из методов - PrepareReportParameters. Этот метод принимает строку ReportParams и анализирует ее, чтобы получить значения параметров. Я загружаю эту строку ReportParams в словарь. А затем проверьте, существуют ли необходимые элементы. Я проверяю это примерно так:

if (ReportParamList.ContainsKey("PAccount"))
{
    ReportParamList.TryGetValue("PAccount", out PrimaryAccount);
}

где PrimaryAccount - статическая переменная в моем классе Common. И я могу получить доступ к этому в другом месте как Common.PrimaryAccount.

Хотя этот способ доступа к параметрам отчета будет работать, но я хочу, чтобы доступ к PrimaryAccount был как Common.ReportParameters.PrimaryAccount. Вот в чем проблема: я не знаю, какой тип ReportParameters должен быть и как мне добавить все параметры отчета к этому типу? Как мне определить параметры отчета? Это кажется осуществимым или бессмысленным. Пожалуйста помоги!


person Sri Reddy    schedule 18.03.2011    source источник


Ответы (3)


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

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

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

РЕДАКТИРОВАТЬ: Хорошо, в настоящее время у вас есть:

public static class Common
{
    public static int PrimaryAccount;
    // other static fields

    public static void PrepareReportParameters(string reportParameters)
    {
        // Code to set the fields
    }
}

Вместо этого используйте обычный класс:

public class ReportParameters
{
    public int PrimaryAccount { get; private set; }
    // Other properties

    private ReportParameters(int primaryAccount, ....)
    {
        this.PrimaryAccount = primaryAccount;
    }

    // Could use a constructor instead, but I prefer methods when they're going to
    // do work
    public static ReportParameters Parse(string report)
    {
        // Parse the parameter, save values into local variables, then
        return new ReportParameters(primaryAccount, ...);
    }
}

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

person Jon Skeet    schedule 18.03.2011
comment
Джон, я добавил этот метод в статический класс, чтобы я мог использовать его во всех других приложениях, где мне нужно анализировать параметры отчета. Этот метод в основном анализирует ReportParams, который имеет более одного параметра, который мне понадобится в моих приложениях. Таким образом, он не может просто вернуть значение основной учетной записи. Да, мне пришлось создать множество статических членов, которых я хочу избежать. - person Sri Reddy; 18.03.2011
comment
@ user465876: Итак, создайте структуру данных, чтобы инкапсулировать все, что вы анализируете, и вернуть это. Посмотрите, что у вас есть как статические члены, и сделайте их членами instance нового типа. - person Jon Skeet; 18.03.2011
comment
:( LOST! Пример действительно поможет. - person Sri Reddy; 18.03.2011
comment
@ user465876: Я привел краткий пример. - person Jon Skeet; 18.03.2011
comment
Хм, единственная проблема, которую я чувствую, заключается в том, что мне нужно поддерживать два класса ReportParameters и мой исходный общий класс, в котором есть остальной общий код. Как вы относитесь к решению Nashwan ниже, где в моем приложении я все еще использую только один - общий класс? - person Sri Reddy; 18.03.2011
comment
@ user465876: Ответ Нашвана по-прежнему предлагает создать другой класс, но с включением статического поля, которое сохраняет ссылку на его экземпляр. Лично я бы избегал этого по причинам, указанным в моем ответе - статическое состояние затрудняет рассуждение и тестирование кода. - person Jon Skeet; 18.03.2011
comment
Джон, спасибо за образец кода и объяснение. Это действительно помогло. Кстати, у меня более 10 параметров отчета, и передачу их в частный конструктор можно упростить, или это нормально? - person Sri Reddy; 18.03.2011
comment
@ user465876: Вы могли просто иметь пустой закрытый конструктор без параметров и устанавливать их через инициализатор объекта: return new ReportParameter { PrimaryAccount = ..., SecondProperty = ... }; - person Jon Skeet; 18.03.2011

Вы можете создать класс ReportParameters с соответствующими строго типизированными свойствами и предоставить Common его статический экземпляр?

person Nashwan    schedule 18.03.2011

Я не уверен, что это лучший дизайн. Есть определенная доля «запаха кода» в том, что Common.PrimaryAccount разрешен только для доступа после вызова PrepareReportParameters. Может быть, вы бы рассмотрели класс экземпляра, передав параметры в конструкторе?

person foson    schedule 18.03.2011