Вопросы о стандартах кодирования C # Ювала Лоуи - PullRequest
23 голосов
/ 16 июня 2009

Мне нравится и очень рекомендую Джувал Лоуи - C # Стандарт кодирования . Юваль явно избегает обоснования для каждой директивы, чтобы придерживаться стандарта (см. Предисловие). Однако есть несколько директив, для которых я нахожу себя любопытным в отношении обоснования.

Каково конкретное обоснование для следующих директив из стандарта Lowy's C #?
Надеемся, что есть жесткие (не субъективные) ответы на них.

1.13 Избегайте полностью определенных имен типов. Вместо этого используйте оператор "using".
Это проблема с производительностью? Иногда мне нужен только один экземпляр полного имени, и добавление с использованием кажется тяжелым.

1.26 Использовать пустые скобки в анонимных методах без параметров. Пропустите круглые скобки, только если анонимный метод мог использоваться с любым делегатом.
На самом деле я просто смущен вторым предложением. Объяснение с примерами поможет, спасибо.

2.19 Избегать определения пользовательских классов исключений
Каковы соображения при минимизации их числа? (Затем он дает указания, если вы их определите (в 2.20).)

2.29 Избегайте использования троичного условного оператора
Слишком сложно для читателя переварить или другие соображения?

2.31 Избегайте вызовов функций в логических условных выражениях. Присвойте локальные переменные и проверьте их.
Я не думаю, что я делаю это, но мне любопытно ... почему бы и нет?

2,47 Избегайте интерфейсов с одним элементом.
Потому что всегда / обычно предпочтительнее делать что? Один метод интерфейсов работает, когда?

2.53 Предпочитают использовать явную реализацию интерфейса
Зачем? Кроме того, Джон Скит не согласен здесь .

Заранее спасибо! Роберт

Ответы [ 8 ]

10 голосов
/ 16 июня 2009

2.29 Избегайте использования троичного условного оператора У меня нет проблем с «простым» использованием троичного оператора, но я рекомендовал не использовать его во вложенном виде:

// This is fine
x := (conditionA) ? true_resultA : false_resultA;

// This would probably be clearer using if-then-elseif
x := (conditionA) ? 
       ((conditionA1) ? true_resultA1 : (condition2) ? true_result2 : false_result2) :
       ((conditionA2) ? true_resultA2 : false_resultA2);
9 голосов
/ 16 июня 2009

Очевидно, я не Юваль, но я могу нанести удар в эти

1.13 Избегайте полностью определенных имен типов. Вместо этого используйте оператор "using".

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

1.26 Используйте пустые скобки для анонимных методов без параметров. Пропустите круглые скобки, только если анонимный метод мог использоваться для любого делегата.

public delegate void Foo1();
public delegate void Foo2(int val);

public void Foo()
{
    Foo1 first = delegate { Console.WriteLine("Hello world"); };
    Foo2 second = delegate { Console.WriteLine("Hello world"); };
    Foo1 third = delegate() { Console.WriteLine("Hello world"); };
    Foo2 fourth = delegate() { Console.WriteLine("Hello world"); }; // does not compile
}

Без паренов анонимный делегат может быть применен к любому делегату. С паренами, вы конкретно относитесь к подписи делегата. Предпочитайте второй синтаксис, если вам не нужна гибкость.

2.19 Избегать определения пользовательских классов исключений

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

2.29 Избегайте использования троичного условного оператора

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

2.31 Избегайте вызовов функций в логических условных выражениях. Присвойте локальные переменные и проверьте их.

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

2.47 Избегайте интерфейсов с одним элементом.

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

2.53 Предпочитают использовать явную реализацию интерфейса

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

5 голосов
/ 16 июня 2009

1,26 соответствует синтаксису до лямбды delegate { }.

// #1 Empty parenthesis on parameterless-anonymous methods would be:
delegate() { }
// #2 ... anonymous method could have been used on any delegate, is:
delegate { }

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

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

4 голосов
/ 22 июня 2009

Относительно 1.13 (Избегайте полностью определенных имен типов. Вместо этого используйте оператор «using»):

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

Класс требует рефакторинга. Использование использования вместо полностью определенных имен классов позволяет легче идентифицировать такие тесно связанные классы.

4 голосов
/ 16 июня 2009

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

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

Например:

2.29 Избегайте использования троичного условного оператора

У меня нет проблем с троичными выражениями как таковыми, но я пишу такой код: int result = CheckMethod ()? OnTrueDoThis (): OnFalseDoThat () ... вы говорите: «У меня есть условие, что если true (или false), вы можете сделать одну и только одну вещь ». Вся конструкция препятствует расширяемости . Вы должны воссоздать конструкцию (с помощью оператора if..else).

Аналогично ...

2.31 Избегайте вызовов функций в логических условных выражениях. Назначить в локальные переменные и проверка по ним.

Вы вызвали функцию и по существу "отбросили" результаты для дальнейшего использования. Если эта информация понадобится позже, либо функцию придется вызывать снова, либо структуру кода придется переписывать. Это также затруднит проверку или запись результатов (для дальнейшей отладки).

Наслаждайтесь

Роберт К. Картейно

3 голосов
/ 16 июня 2009

Это мой лучший ответ на вопросы, которые вы перечислили. Из тех, что я не могу сказать, я опущен.

1.13 Избегайте полностью определенных имен типов. Вместо этого используйте оператор "using".

читаемость. Должно быть сложнее читать код, когда вы должны прочитать полностью определенные имена типов.

2.19 Избегать определения пользовательских классов исключений

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

2.29 Избегайте использования троичного условного оператора

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

2.47 Избегайте интерфейсов с одним членом.

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

2.31 Избегайте вызовов функций в логических условных выражениях. Присвойте локальные переменные и проверьте их.

Несколько причин, о которых я могу подумать здесь. Читаемость. Это может затруднить понимание условных операторов, если вы выполняете в них вызовы функций. Кроме того, сложнее отлаживать, если вы не смотрите.

2.53 Предпочитают использовать явную реализацию интерфейса

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

2 голосов
/ 16 июня 2009

Вот некоторые из моих реакций, на которые я осмелюсь ответить:)

1.13 Избегайте полностью определенных имен типов. Вместо этого используйте оператор "using". Я не согласен. Это, конечно, не связано с производительностью. Это может привести к улучшению читабельности, чтобы иметь var foo = new Foo() вместо var foo = new MyCompany.MyNamespace.Helpers.Xml.Foo(), но кроме этого - нет.

2.19 Избегать определения пользовательских классов исключений Это ерунда имхо. Вам следует избегать создания пользовательских исключений, которые являются производными от ApplicationException, но в пользовательских исключениях нет ничего плохого (если вы не собираетесь заново изобретать существующие исключения).

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

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

2.47 Избегать интерфейсов с одним членом. Я также не согласен здесь. Вы должны избегать интерфейсов «маркер» - интерфейсы без маркера, но которые просто служат для того, чтобы что-то было «... блек». Но один метод интерфейса мне подходит.

0 голосов
/ 29 ноября 2011

2,29 Тернарный оператор

Для начала, если вы начнете использовать троичный оператор, должна быть причина для использования троичного оператора вместо обычного if-then-else. Наблюдать:

if (x == 0) {...} else{...} //A set of statements demand a regular If-then-else

//A simple assignment can be handled by the ternary operator
y = (x == 0)? 1 : 0 //this is readable and how it should be used


(x==0)? callSomething() : callSomethingElse() //this is NOT how it should be used

Тернарный оператор предназначен для возврата одного из двух значений в зависимости от того, какое условие он оценивает. Это очень удобно при выполнении FP. Для операторов вызова, которые не возвращают значение, вы должны вернуться к if-then-else.

...