Можно ли использовать назначения в выражениях? - PullRequest
1 голос
/ 06 ноября 2008

Я наткнулся на этот код и хотел, чтобы другие высказали свою точку зрения ... это хорошо или плохо? ;)

Class ReportClass
{
 public string ReportName {get; set;}
}

Тогда это было использовано следующим образом в коде:

displayReport(ReportClass.ReportName = cmbReportName.SelectedValue.ToString())

Это самый простой пример формы, который я могу вам дать. Вопрос ... почему я не могу найти примеры? Как бы это называется? Это просто напрашивается на неприятности?

РЕДАКТИРОВАТЬ: Я имею в виду назначение на месте. О чем я не знал до сегодняшнего дня

Ответы [ 9 ]

5 голосов
/ 06 ноября 2008

Я стараюсь избегать назначения на месте - или вообще каких-либо побочных эффектов, подобных этому - за исключением одного распространенного выражения:

string line;
while ((line = reader.ReadLine()) != null)
{
    // Do something with line    
}

(и варианты для чтения потоков и т. Д.)

Я также в порядке с использованием инициализаторов объектов в вызовах параметров, например,

Foo(new Bar { X=1, Y=2 });

но присвоение свойства существующему объекту ... ну, это все субъективно, но это не моя чашка чая.

4 голосов
/ 06 ноября 2008

Это совершенно нормально. Оба.

  • Автоматические свойства (вещь {get; set;}): введено в C #. Очень полезная функция.
  • Назначение в параметрах: Редко используется в C #, но полностью легально. Обычно он присваивает значение выражения справа от оператора присваивания (=) свойству объекту слева, а затем передает это значение методу.

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

4 голосов
/ 06 ноября 2008

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

ReportClass.ReportName = cmbReportName.SelectedValue.ToString();
displayReport(ReportClass.ReportName);

Я никогда не был фанатом составных высказываний.

2 голосов
/ 06 ноября 2008

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

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

2 голосов
/ 06 ноября 2008

В Руководстве по проектированию Microsoft Framework не рекомендуется размещать несколько операторов в одной строке, кроме случаев, когда существует прямая языковая поддержка, например, в операторе for. Поскольку существует явная языковая поддержка множественного назначения,

int a, b, c;
a = b = c = 0;

разрешено. С другой стороны, код формы, используемой в вашем примере, не рекомендуется.

Как насчет этого, люди?

while ((packetPos = Packet.FindStart(buffer, nextUnconsideredPos)) > -1)

Чтобы избежать встроенного присваивания, вы должны использовать избыточный коэффициент, например:

packetPosition = Packet.FindStart(buffer, nextUnconsideredPosition);
while (packetPosition > -1)
{
  ...
  packetPosition = Packet.FindStart(buffer, nextUnconsideredPosition);
}
2 голосов
/ 06 ноября 2008

Вы имели в виду автоматические свойства или назначение на месте?

Зависит от вашей команды ИМО. Если ваша команда состояла из разработчиков в стиле C Тогда я думаю, что все в порядке.

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

Примеры? Оператор присваивания (=) в языках C также возвращает присвоенные ему значения.

var a = 0;
var b = 0;

// This makes a *and* b equals to 1
a = b = 1; 

// This line prints 3 and a is now equals to 3
Console.WriteLine(a = 3);

// This line prints 7 and a and b is now equals to 7
Console.WriteLine(a = b = 7);

Я думаю, вполне естественно, что такое назначение происходит. Потому что языки C, кажется, поощряют сокращенную запись IMO.

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

displayReport(
    ReportClass.ReportName = cmbReportName.SelectedValue.ToString());

Проясните свои намерения, когда каждый составленный оператор находится в разных строках. (но все же составное утверждение)

Или сначала извлеките правую часть в собственную переменную, например,

var reportName = cmbReportName.SelectedValue.ToString();

displayReport(ReportClass.ReportName = reportName);

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

0 голосов
/ 07 ноября 2008

Что касается присвоения имени свойству, у вас есть ReportClass, я бы изменил его на Report, а свойство на нем изменилось с ReportName на просто Name. Экономит вас при наборе текста (хотя да, intellisense доступен). Выглядит лучше при кодировании как Report.Name.

Я знаю, это немного не по теме, но эй, хо

0 голосов
/ 06 ноября 2008

Это действительно правильный код? Для меня это выглядит как статический класс.

Я бы догадался, что ты использовал это так:

displayReport(new ReportClass { ReportName = cmbReportName.SelectedValue.ToString() } )
0 голосов
/ 06 ноября 2008

Кажется, хорошо для меня. Вероятно, он скомпилирован с C # 3.0, и это позволяет C # автоматические свойства .

...