Являются ли "свойства прокси" хорошим стилем? - PullRequest
3 голосов
/ 18 сентября 2008

У меня есть класс со строковым свойством, который на самом деле состоит из нескольких строк, соединенных с разделителем.

Мне интересно, если это хорошая форма иметь свойство прокси, как это:

public string ActualProperty
{
    get { return actualProperty; }
    set { actualProperty = value; }
}

public string[] IndividualStrings
{
    get { return ActualProperty.Split(.....); }
    set 
    { 
            // join strings from array in propval .... ;
            ActualProperty = propval;
    }
}

Есть ли какие-то риски, которые я упустил из виду?

Ответы [ 6 ]

2 голосов
/ 18 сентября 2008

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

Я думаю, я бы;

  • сохранить массив как свойство
  • предоставить метод GetJoinedString(string seperator).
  • предоставляет метод SetStrings(string joined, string seperator) или Parse(string joined, string seperator).

Реально, разделитель в строках на самом деле не часть класса, а эфемерная деталь. Сделайте ссылки на него явными, чтобы, например, приложение CSV могло пропустить запятую, а приложение с разделителями табуляции могло пропустить вкладку. Это сделает ваше приложение проще в обслуживании. Кроме того, это устраняет эту неприятную проблему наличия двух методов получения и установки для одних и тех же фактических данных.

2 голосов
/ 18 сентября 2008

Объединение двух устанавливаемых свойств, по моему мнению, плохо. Переключитесь на использование явных методов get / set вместо свойства, если это действительно то, что вам нужно. Код, имеющий неочевидные побочные эффекты, почти всегда будет кусать вас позже. Делайте вещи максимально простыми и понятными.

Кроме того, если у вас есть свойство, представляющее собой отформатированную строку, содержащую подстроки, похоже, что вам действительно нужна отдельная структура / класс для этого свойства вместо неправильного использования примитивного типа.

1 голос
/ 06 марта 2010

Свойства предназначены для очень простых членов класса; получение или установка значения свойства следует рассматривать как тривиальную операцию без существенных побочных эффектов .

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

«Сложное» свойство опасно, потому что оно не соответствует ожиданиям звонящих. Свойства интерпретируются как поля (с побочными эффектами), но как поля, вы ожидаете, что сможете назначить значение, а затем впоследствии получить это значение. Таким образом, вызывающая сторона должна ожидать, что она сможет назначить несколько свойств и получить их значения позже.

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

Дополнительно, в сторону:

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

Например:

YourClass i = new YourClass();
i.IndividualStrings[0] = "Hello temporary array!";

Этот код выглядит так, как будто он изменяет значение в свойстве IndividualStrings, но на самом деле массив создается свойством и нигде не назначается, поэтому массив и изменение немедленно выпадут из области видимости.

public string ActualProperty { get; set; }

public string[] GetIndividualStrings()
{
    return ActualProperty.Split(.....);
}

public void SetFromIndividualStrings(string[] values)
{
    // join strings from array .... ;
}
1 голос
/ 18 сентября 2008

Определите «хорошо». Он не должен сломаться (если вы не смогли должным образом гарантировать, что разделитель (и), переданный в Split(), никогда не будет разрешен в самих отдельных строках), но если к IndividualStrings обращаются чаще, чем ActualProperty, вы закончите до парсинга actualProperty гораздо чаще, чем нужно. Конечно, если верно обратное, то у вас все хорошо ... и если оба они вызываются так часто, что любой ненужный синтаксический анализ или объединение недопустимы, просто сохраните оба и выполните повторный анализ при изменении значения.

0 голосов
/ 18 сентября 2008

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

Как минимум, я бы удалил установщик свойства IndividualStrings или переместил бы его в два метода: string [] SplitActualProperty () и void MergeToActualProperty (string [] parts).

0 голосов
/ 18 сентября 2008

Ну, я бы сказал, что ваш «набор» - это высокий риск, что если кто-то не знает, что ему нужно передать уже объединенную последовательность значений, или ваш пример выше может пропустить это. Что, если строка уже содержит разделитель - вы сломаете.

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

...