Создать новый экземпляр или просто установить внутренние переменные - PullRequest
1 голос
/ 13 апреля 2009

Я написал вспомогательный класс, который принимает строку в конструкторе и предоставляет множество свойств Get для возврата различных аспектов строки. В настоящее время единственный способ установить строку - через конструктор, и после ее установки ее нельзя изменить. Так как у этого класса есть только одна внутренняя переменная (строка), мне было интересно, следует ли мне сохранить ее таким образом, или я должен также разрешить установку строки?

Некоторые примеры кода моей помощи, почему я спрашиваю:

StreamReader stream = new StreamReader("ScannedFile.dat");
ScannerLine line = null;
int responses = 0;
while (!stream.EndOfStream)
{
  line = new ScannerLine(stream.ReadLine());
  if (line.IsValid && !line.IsKey && line.HasResponses)
    responses++;
}

Выше приведен быстрый пример подсчета количества действительных ответов в данном отсканированном файле. Будет ли выгоднее вместо этого кодировать это?

StreamReader stream = new StreamReader("ScannedFile.dat");
ScannerLine line = new ScannerLine();
int responses = 0;
while (!stream.EndOfStream)
{
  line.RawLine = stream.ReadLine();
  if (line.IsValid && !line.IsKey && line.HasResponses)
    responses++;
}

Этот код используется в серверной части веб-приложения ASP.net и должен быть адаптивным. Я знаю, что это может быть причиной преждевременной оптимизации, но я пишу это для отзывчивости на стороне клиента и удобства обслуживания.

Спасибо!

РЕДАКТИРОВАТЬ - Я решил также включить конструктор класса (Да, это действительно так.):

public class ScannerLine
{
  private string line;
  public ScannerLine(string line)
  {
    this.line = line;
  }

  /// <summary>Gets the date the exam was scanned.</summary>
  public DateTime ScanDate
  {
    get
    {
      DateTime test = DateTime.MinValue;
      DateTime.TryParseExact(line.Substring(12, 6).Trim(), "MMddyy", CultureInfo.InvariantCulture, DateTimeStyles.None, out test);
      return test;
    }
  }

  /// <summary>Gets a value indicating whether to use raw scoring.</summary>
  public bool UseRaw { get { return (line.Substring(112, 1) == "R" ? true : false); } }

  /// <summary>Gets the raw points per question.</summary>
  public float RawPoints
  {
    get
    {
      float test = float.MinValue;
      float.TryParse(line.Substring(113, 4).Insert(2, "."), out test);
      return test;
    }
  }
}

** РЕДАКТИРОВАТЬ 2 - ** Я включил некоторые примеры свойств класса, чтобы помочь прояснить. Как вы можете видеть, класс берет фиксированную строку из сканера и просто упрощает разбиение строки на более полезные куски. Файл представляет собой файл с разделителями строк с компьютера Scantron, и единственный способ его анализа - это набор строк. Вызовы и преобразования в подстроки.

Ответы [ 6 ]

4 голосов
/ 13 апреля 2009

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

Однако, если ваше состояние - просто строка, действительно ли вы предоставляете большую выгоду по сравнению с простым хранением строк и наличием соответствующих методов для их последующего анализа? ScannerLine анализирует строку и кэширует этот анализ, или это действительно просто набор методов анализа?

0 голосов
/ 13 апреля 2009

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

0 голосов
/ 13 апреля 2009

Я бы на самом деле полностью исключил природу класса «экземпляр» и использовал бы его как статический класс, а не экземпляр, как вы сейчас. Каждое свойство полностью независимо друг от друга, за исключением используемой строки. Если бы эти свойства были связаны друг с другом, и / или были другие «скрытые» переменные, которые устанавливались каждый раз, когда была назначена строка (например, предварительно обрабатывая свойства), то были бы причины сделать это один. так или иначе с повторным назначением, но из того, что вы там делаете, я бы изменил его на 100% статические методы класса.

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

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

0 голосов
/ 13 апреля 2009

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

0 голосов
/ 13 апреля 2009

Я бы пошел со вторым вариантом. Это более эффективно, и они оба одинаково легко понять IMO. Кроме того, у вас, вероятно, нет возможности узнать, сколько раз будут вызываться эти операторы в цикле while. Так кто знает? Это может быть увеличение производительности на 0,01% или увеличение производительности на 50% (маловероятно, но возможно)!

0 голосов
/ 13 апреля 2009

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

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