Подтвердить что ты не робот

С# Antipatterns

Короче говоря: я нахожу Java antipatterns незаменимым ресурсом. Для новичков, как и для профессионалов. Мне еще нужно найти что-то подобное для С#. Поэтому я открою этот вопрос в качестве вики сообщества и приглашаю всех поделиться своими знаниями об этом. Поскольку я новичок в С#, я сильно заинтересован в этом, но не могу начать с некоторых antipatterns:/

Вот ответы, которые я нахожу специально для С#, а не других языков.

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


Бросок NullReferenceException

Выброс неправильного исключения:

if (FooLicenceKeyHolder == null)
    throw new NullReferenceException();

Свойства и общедоступные переменные

Открытые переменные в классах (вместо этого используйте свойство).

Если класс не является простым объектом передачи данных.


Не понимая, что bool - это реальный тип, а не только соглашение

if (myBooleanVariable == true)
{
    ...
}

или, даже лучше

if (myBooleanVariable != false)
{
    ...
}

Такие конструкции часто используются разработчиками C и C++, где идея логического значения была просто условным (0 == false, все остальное верно); это необязательно (или желательно) на С# или на других языках, имеющих реальные булевы.


Использование using()

Не используйте using, если это необходимо:

object variable;
variable.close(); //Old code, use IDisposable if available.
variable.Dispose(); //Same as close.  Avoid if possible use the using() { } pattern.
variable = null; //1. in release optimised away.  2. C# is GC so this doesn't do what was intended anyway.
4b9b3361

Ответ 1

Неправильное создание исключения. Чтобы восстановить исключение:

try
{
    // do some stuff here
}
catch (Exception ex)
{
    throw ex;  // INCORRECT
    throw;     // CORRECT
    throw new Exception("There was an error"); // INCORRECT
    throw new Exception("There was an error", ex); // CORRECT
}

Ответ 2

GC.Collect() собирать вместо того, чтобы доверять сборщику мусора.

Ответ 3

Я вижу это слишком много, как в Java, так и в С#...

if(something == true){
  somethingelse = true;
}

с бонусами, если он также имеет

else{
  somethingelse = false;
}

Ответ 4

using Microsoft.SharePoint;

'nuff сказал

Ответ 5

Я вижу следующий код много:

if (i==3)
       return true;
else
       return false;

должен быть:

       return (i==3);

Ответ 6

Оскорбление закона Деметры:

a.PropertyA.PropertyC.PropertyB.PropertyE.PropertyA = 
     b.PropertyC.PropertyE.PropertyA;

Ответ 7

Бросок NullReferenceException:

if (FooLicenceKeyHolder == null)
    throw new NullReferenceException();

Ответ 8

Это правда, что я видел это своими глазами.

public object GetNull()
{
     return null;
}

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

который сделал мой день.

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

Ответ 9

int foo = 100;
int bar = int.Parse(foo.ToString());

Или более общий случай:

object foo = 100;
int bar = int.Parse(foo.ToString());

Ответ 10

Я нашел это в нашем проекте и чуть не сломал стул...

DateTime date = new DateTime(DateTime.Today.Year, 
                             DateTime.Today.Month, 
                             DateTime.Today.Day);

Ответ 11

Довольно часто я натыкаюсь на такое вар-злоупотребление:

var ok = Bar();

или даже лучше:

var i = AnyThing();

Использование var таким образом не имеет смысла и ничего не получает. Это просто делает код труднее следовать.

Ответ 12

Ответ 13

Не понимая, что bool - это реальный тип, а не только соглашение

if (myBooleanVariable == true)
{
    ...
}

или, даже лучше

if (myBooleanVariable != false)
{
    ...
}

Такие конструкции часто используются разработчиками C и C++, где идея логического значения была просто условным (0 == false, все остальное верно); это необязательно (или желательно) на С# или на других языках, имеющих реальные булевы.

Обновлено: перефразировал последний абзац, чтобы улучшить его ясность.

Ответ 14

Открытые переменные в классах (вместо этого используйте свойство).

Если класс не является простым объектом передачи данных.

См. комментарии ниже для обсуждения и разъяснения.

Ответ 15

Я действительно видел это.

bool isAvailable = CheckIfAvailable();
if (isAvailable.Equals(true))
{ 
   //Do Something
}

превосходит isAvailable == true руки против шаблона!
Это супер-анти-шаблон!

Ответ 16

object variable;
variable.close(); //Old code, use IDisposable if available.
variable.Dispose(); //Same as close.  Avoid if possible use the using() { } pattern.
variable = null; //1. in release optimised away.  2. C# is GC so this doesn't do what was intended anyway.

Ответ 17

Частные автоматические свойства:

private Boolean MenuExtended { get; set; }

Ответ 18

Объявление и инициализация всех локальных переменных в верхней части каждого метода настолько уродлива!

void Foo()
{
    string message;
    int i, j, x, y;
    DateTime date;

    // Code
}

Ответ 19

Две строковые анти-шаблоны
Анти-шаблон № 1
Проверка строк для нулевого или пустого

//Bad
if( myString == null || myString == "" )
OR
if( myString == null || myString.Length == 0 )

//Good
string.IsNullOrEmpty(myString)

Anti-Pattern # 2 (только для .NET 4.0)
Проверка строк для нулевого или пустого или белого пространства

//Bad
if( myString == null || myString == "" || myString.Trim() == "")

//Good
string.IsNullOrWhiteSpace(myString) 

Ответ 20

Неправильное литье (пожалуйста, доверяйте компилятору):

foreach (UserControl view in workspace.SmartParts)
{
  UserControl userControl = (UserControl)view;
  views.Add(userControl);
}

Ответ 21

if(data != null)
{
  variable = data;
}
else
{
  variable = new Data();
}

лучше писать как

variable = (data != null) ? data : new Data();

и даже лучше написано как

variable = data ?? new Data();

Последний список кодов работает в .NET 2.0 и выше

Ответ 22

Разговор с акцентом всегда меня поймал.

Программисты на С++:

if (1 == variable) { }

В С# это даст вам ошибку компилятора, если вы наберете if (1 = variable), что позволит вам написать код так, как вы хотите сказать, вместо того, чтобы беспокоиться о том, чтобы стрелять себе в ногу.

Ответ 23

Не использовать тернар - это то, что я вижу, обращается в С# иногда

вы видите:

private string foo = string.Empty;
if(someCondition)
  foo = "fapfapfap";
else
  foo = "squishsquishsquish";

вместо:

private string foo  = someCondition ? "fapfapfap" : "squishsquishsquish";

Ответ 24

Доступ к измененным закрытиям

foreach (string list in lists)
{
        Button btn = new Button();
        btn.Click += new EventHandler(delegate { MessageBox.Show(list); });
}

(см. ссылку для объяснения и исправления)

Ответ 25

Для конкретизации произвольного количества строк с использованием конкатенации строк вместо строкового построителя

Exampls

foreach (string anItem in list)
    message = message + anItem;

Ответ 26

считается общим?

public static main(string [] args)
{
  quit = false;
  do
  {
  try
  {
      // application runs here .. 
      quit = true;
  }catch { }
  }while(quit == false);
}

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

Ответ 27

В проекте, в котором я участвую, было пятьдесят классов, все наследуемые от одного и того же класса, которые определены:

public void FormatZipCode(String zipCode) { ... }

Либо поставьте его в родительский класс, либо в класс утилиты. Argh.

Рассматривали ли вы просмотр The Daily WTF?

Ответ 28

Массивно чрезмерно сложные методы 'Page_Load', которые хотят сделать все.

Ответ 29

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

Ответ 30

Нашел это несколько раз в системе, которую я унаследовал...

if(condition){
  some=code;
}
else
{
  //do nothing
}

и наоборот

if(condition){
  //do nothing
}
else
{
  some=code;
}