2010-07-06 29 views
16

Czasami używam nawiasów klamrowych, aby wyizolować blok kodu, aby uniknąć błędnego użycia zmiennej później. Na przykład, kiedy wstawiam kilka takich samych metod, często kopiuję i wkleja bloki kodu, kończąc na mieszaniu nazw i wykonywaniu podwójnych poleceń. Dodanie szelek pomaga uniknąć tej sytuacji, ponieważ użycie niewłaściwego SqlCommand w niewłaściwym miejscu spowoduje błąd. Oto ilustracja:Czy korzystanie z nawiasów klamrowych jest niewłaściwe w celu zmiany zakresu?

Collection<string> existingCategories = new Collection<string>(); 

// Here a beginning of a block 
{ 
    SqlCommand getCategories = new SqlCommand("select Title from Movie.Category where SourceId = @sourceId", sqlConnection, sqlTransaction); 
    getCategories.Parameters.AddWithValue("@sourceId", sourceId); 
    using (SqlDataReader categoriesReader = getCategories.ExecuteReader(System.Data.CommandBehavior.SingleResult)) 
    { 
     while (categoriesReader.Read()) 
     { 
      existingCategories.Add(categoriesReader["Title"].ToString()); 
     } 
    } 
} 

if (!existingCategories.Contains(newCategory)) 
{ 
    SqlCommand addCategory = new SqlCommand("insert into Movie.Category (SourceId, Title) values (@sourceId, @title)", sqlConnection, sqlTransaction); 

    // Now try to make a mistake and write/copy-paste getCategories instead of addCategory. It will not compile. 
    addCategory.Parameters.AddWithValue("@sourceId", sourceId); 
    addCategory.Parameters.AddWithValue("@title", newCategory); 
    addCategory.ExecuteNonQuery(); 
} 

Teraz StyleCop wyświetla ostrzeżenie za każdym razem, gdy blok podąża za pustą linią. Z drugiej strony, nie umieszczenie pustej linii sprawiłoby, że kod byłby trudniejszy do zrozumienia.

// Something like: 
Collection<string> existingCategories = new Collection<string>(); 
{ 
    // Code here 
} 

// can be understood as (is it easy to notice that semicolon is missing?): 
Collection<string> existingCategories = new Collection<string>() 
{ 
    // Code here 
} 

Więc

  1. Czy istnieje coś złego w użyciu szelki tworzyć bloki kodu tylko dla celów zmiennym?

  2. Jeśli wszystko jest w porządku, jak uczynić go bardziej czytelnym bez naruszania reguł StyleCop?

+3

Są to tak zwane anonimowe bloki. Powiązane: http://stackoverflow.com/questions/85282/what-is-the-value-of-an-anonymous-unattached-block-in-c i http://stackoverflow.com/questions/500006/what- jest-cel-z-anonimowych-blokuje-w-stylu-językach-języków –

Odpowiedz

5

Nie sądzę, że jest coś złego w używaniu nawiasów klamrowych w celu ograniczenia zakresu - czasami może być bardzo przydatne.

Przypadek - natknąłem się na bibliotekę profilowania, która kiedyś wykorzystywała obiekty Profile do odcinania sekcji kodu. Prace te polegały na mierzeniu czasu od ich stworzenia do zniszczenia i dlatego działały najlepiej, tworząc je na stosie, a następnie niszcząc, gdy wykraczały poza zakres, mierząc czas spędzony w tym konkretnym zakresie. Jeśli chcesz odmienić czas, który z natury nie ma swojego zakresu, dodanie dodatkowych nawiasów klamrowych w celu zdefiniowania tego zakresu jest prawdopodobnie najlepszym sposobem.

Co do czytelności, mogę zrozumieć, dlaczego StyleCop jej nie lubi, ale każdy, kto ma jakiekolwiek doświadczenie w C/C++/Java/C#/... wie, że para brasów definiuje zakres i powinna być sprawiedliwa oczywiste, że to właśnie próbujesz zrobić.

12

Użyj oświadczenie using zamiast gołych bloków usztywniających.

Pozwoli to uniknąć ostrzeżeń, a także sprawi, że kod będzie bardziej wydajny pod względem zasobów.

Z szerszej perspektywy należy rozważyć podział tej metody na mniejsze metody. Używanie jednego z nich jest zazwyczaj lepiej wykonywane przez wywołanie jednej metody, a następnie drugiej. Każda metoda użyje wtedy lokalnego lokalnego SqlCommand.

+8

Wierzę, że using() wymaga IDisposable, którego może nie mieć w tym kontekście. –

+0

Odnosi się to do tego szczególnego scenariusza (ponieważ 'SqlCommand' implementuje' IDisposable', ale nie rozwiązałoby to jego ogólnej sprawy –

+0

To jest brzydkie, ale nie możesz użyć 'do {...} while (false);' zamiast Wyłączenie ostrzeżenia prawdopodobnie byłoby lepszym rozwiązaniem, jednak: –

18

Nie ma nic złego per se z blokowaniem kodu, ale musisz wziąć pod uwagę, dlaczego to robisz.

Jeśli kopiujesz i wklejasz kod, najprawdopodobniej znajdziesz się w sytuacji, w której powinieneś refaktoryzować kod i wywoływać wielokrotnie wywoływane funkcje, zamiast powtarzać podobne, ale różne bloki kodu.

+4

Zgadzam się, nie ma niczego z technicznego punktu widzenia, jest to skarga stylistyczna i potencjalnie ostrzeżenie o długich funkcjach, które naprawdę powinny zostać podzielone na mniejsze i łatwiejsze w zarządzaniu części. –

+0

"Prawdopodobnie będziesz w sytuacji, w której powinieneś modyfikować kod": nie chodzi o kopiowanie/wklejanie dużych bloków kodu. Ten sam problem pojawi się podczas używania IntelliSense, jeśli dwie zmienne mają podobne nazwy ('sqlGetProductFromTable' vs.' sqlAddProductToTable'). Łatwo jest błędnie wpisać nazwę zmiennej, a ponieważ dla kompilatora kod jest całkowicie poprawny, zostanie wykonany, ale wygeneruje coś nieoczekiwanego. –

+0

@MainMa: Ponowne użycie bloków nie jest jedynym powodem do refaktoryzacji. Metoda, która jest po prostu ogromna, może sama w sobie stanowić dobry powód do rozbicia jej na mniejsze części. –

4

Myślę, że takie klocki to dobry pomysł, używam ich często. Jest to przydatne, gdy trzeba oddzielić bloki kodu, które są zbyt małe, aby można je było wyodrębnić, lub gdy metoda składa się z kilku bloków kodu , wygląda jak, ale nie z tą samą logiką. Pozwala nadawać zmienne te same nazwy bez nazywania konfliktów, a to sprawia, że ​​treść metody jest bardziej czytelna.

Nawiasem mówiąc, moja opinia StyleCop ma domyślny zestaw reguł z większą ilością reguł, których celowość jest dyskusyjna.

3

Powiedziałabym, że gdybym pracował nad tym kodem, byłabym trochę niefrasobliwa przy użyciu zakresu. To nie, Afaiku, powszechna praktyka.

Uważam, że to zapach, który robisz. Sądzę, że lepszą praktyką byłoby zerwanie każdego zakresu w ramach własnej metody z całkowicie opisowymi nazwami i dokumentacją.

0

Jeśli chcesz użyć nawiasów klamrowych w celu ograniczenia zakresu zmiennych, twoje metody są prawdopodobnie zbyt długie. Chciałem tylko podkreślić to, co inni już napisali.