Стиль кодирования: назначения внутри выражений? - PullRequest
11 голосов
/ 17 февраля 2011

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


Опция ①

// How many spaces are there in the beginning of string? (and remove them)
int spaces = text.Length;
text = text.TrimStart(' ');
spaces -= text.Length;
  • Преимущество: Назначение на отдельной строке, поэтому побочный эффект явный
  • Недостаток: Первая строка выглядит бессмысленной сама по себе; Вы должны заметить третью строку, чтобы понять это

Опция ②

// How many spaces are there in the beginning of string? (and remove them)
int spaces = text.Length - (text = text.TrimStart(' ')).Length;
  • Преимущество: Оператор имеет смысл с точки зрения вычислений, которые он выполняет
  • Недостаток: Задание вроде как скрыто внутри выражения; побочный эффект можно не заметить

Ответы [ 6 ]

36 голосов
/ 17 февраля 2011

Мне не нравится ни один из них.Некоторые рекомендации по написанию понятного кода:

  • Значение переменной должно оставаться неизменным в течение всего времени существования переменной.

Опция (1) нарушает это руководство;переменная «пробелы» комментируется как означающая «сколько пробелов в тексте», но она никогда не имеет такого значения!Время жизни начинается с количества символов в тексте и заканчивается временем жизни как количеством пробелов, которые были в тексте.Это означает две разные вещи на протяжении всей своей жизни, и ни одна из них не является тем, что указано в документации.

  • Выражение выражения имеет ровно один побочный эффект.(«Оператор выражения» - это оператор, состоящий из одного выражения; в C # допустимыми выражениями оператора являются вызовы методов, конструкции объектов, приращения, уменьшения и назначения.)

  • Выражениене имеет побочных эффектов, кроме случаев, когда выражение является единственным побочным эффектом оператора выражения.

Опция (2) явно нарушает эти рекомендации.Трудно рассуждать о выражениях выражений, которые вызывают множество побочных эффектов, их сложно отлаживать, потому что вы не можете поставить точки останова там, где вам это нужно, это все плохо.рекомендации.

string originalText = text;
string trimmedText = originalText.TrimStart(' ');
int removedSpaces = originalText.Length - trimmedText.Length;
text = trimmedText;

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

12 голосов
/ 17 февраля 2011

Я бы сделал вариант 1b:

int initial_length = text.Length;
text = text.TrimStart(' ');
int spaces = initial_length - text.Length;

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

1 голос
/ 17 февраля 2011

А как насчет перегрузки?

public static string TrimStart(this string s, char c, out int numCharsTrimmed) 
{
    numCharsTrimmed = s.Length;
    s = s.TrimStart(c);
    numCharsTrimmed -= s.Length;    
}
1 голос
/ 17 февраля 2011

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

0 голосов
/ 17 февраля 2011

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

0 голосов
/ 17 февраля 2011

Вариант ① Весь день.Это читабельно.Вариант maintain гораздо сложнее поддерживать.

...