Widziałem innych programistów używających klas statycznych jako przestrzeni nazw
public static class CategoryA
{
public class Item1
{
public void DoSomething() { }
}
public class Item2
{
public void DoSomething() { }
}
}
public static class CategoryB
{
public class Item3
{
public void DoSomething() { }
}
public class Item4
{
public void DoSomething() { }
}
}
Aby utworzyć instancję klas wewnętrznych, będzie to wyglądać następująco
CategoryA.Item1 item = new CategoryA.Item1();
Uzasadnieniem jest to, że przestrzenie nazw można ukryć za pomocą słowa kluczowego „using”. Ale używając klas statycznych, należy określić nazwy klas warstw zewnętrznych, co skutecznie zachowuje przestrzenie nazw.
Microsoft odradza to w wytycznych . Osobiście uważam, że wpływa to na czytelność. Jakie są Twoje myśli?
c#
c++
object-oriented
static-typing
namespace
użytkownik394128
źródło
źródło
Odpowiedzi:
Używanie klas statycznych jako przestrzeni nazw jest sprzeczne z celem posiadania przestrzeni nazw.
Kluczowa różnica jest tutaj:
Jeśli zdefiniujesz
CategoryA
,CategoryB<
jako przestrzenie nazw i gdy aplikacja używa dwóch przestrzeni nazw:W przypadku, gdy
CategoryA
lubCategoryB
jest klasą statyczną, a nie przestrzenią nazw, użycie aplikacji jest prawie takie samo, jak opisano powyżej.Jeśli jednak zdefiniujesz go jako przestrzeń nazw, a aplikacja używa tylko 1 przestrzeni nazw (nie obejmuje
CategoryB
), w takim przypadku aplikacja może faktycznie użyć następującychAle gdybyś zdefiniował
CategoryA
jako klasę statyczną, powyższe nie jest zdefiniowane! ZaCategoryA.something
każdym razem trzeba pisać .Przestrzeni nazw należy używać, aby uniknąć konfliktów nazw, natomiast hierarchii klas należy używać, gdy grupowanie klas ma pewne znaczenie dla modelu systemu.
źródło
using Item1 = CategoryA.Item1
(myślę, że działa to w przypadku klas zagnieżdżonych, tak jak w przypadku przestrzeni nazw)var s = new HideMe.MyPhoneNumberIs12345678.TheRealUsefulClass()
Cokolwiek się tu dzieje, z pewnością nie jest idiomatycznym kodem C #.
Może ci inni próbują zaimplementować wzorzec modułu - pozwoliłoby to mieć funkcje, akcje itd., A także klasy w „przestrzeni nazw” (tj. W tym przypadku klasę statyczną)?
źródło
Przede wszystkim każda klasa powinna znajdować się w przestrzeni nazw, więc twój przykład byłby bardziej podobny do:
To powiedziawszy, nie widzę korzyści z tego rodzaju gimnastyki w kodzie, gdy równie dobrze można zdefiniować taką przestrzeń nazw:
Jeśli zastanawiasz się kiedyś nad przechowywaniem niektórych metod statycznych na poziomie wyższej klasy, może to mieć sens, ale twórcy C # nie mają tego na myśli i mogą uczynić go mniej czytelnym dla innych - zmarnowałbym dużo czasu myślenie DLACZEGO to zrobiłeś i zastanawianie się, czy brakuje mi jakiegoś pliku źródłowego zawierającego wyjaśnienia.
źródło
Przestrzenie nazw w języku Java, JavaScript i .NET nie są kompletne i pozwalają tylko na przechowywanie klas, ale inne rzeczy, takie jak stałe lub metody globalne, nie.
Wielu programistów stosuje sztuczki „klas statycznych” lub „metod statycznych”, nawet jeśli niektórzy ludzie tego nie zalecają.
źródło
Wiem, że jest to stare pytanie, ale jednym z bardzo uzasadnionych powodów używania klasy jako przestrzeni nazw (w tym niestatycznej) jest to, że C # nie obsługuje definicji parametrycznych lub ogólnych przestrzeni nazw. Napisałem post na blogu na ten właśnie temat tutaj: http://tyreejackson.com/generics-net-part5-generic-namespaces/ .
Jego sedno polega na tym, że gdy używa się generics do abstrakcyjnego pokrywania ogromnego obszaru kodu, czasem konieczne jest współdzielenie wielu ogólnych parametrów między pokrewnymi klasami i interfejsami. Konwencjonalnym sposobem na to byłoby ponowne zdefiniowanie ogólnych parametrów, ograniczeń i wszystkich w każdym interfejsie i sygnaturze klasy. Z czasem może to prowadzić do mnożenia parametrów i ograniczeń, nie mówiąc już o konieczności ciągłego kwalifikowania powiązanych typów poprzez przekazywanie parametrów typu z jednego typu do argumentów typu powiązanego typu.
Użycie zewnętrznej klasy Generic i zagnieżdżenie powiązanych typów może radykalnie WYSUSIĆ kod i uprościć jego abstrakcję. Następnie można wyprowadzić parametryczną klasę przestrzeni nazw z konkretną implementacją, która dostarcza wszystkie konkretne szczegóły.
Oto prosty przykład:
Używany w ten sposób:
Korzystaj z pochodnych w następujący sposób:
Korzyścią z pisania typów w ten sposób jest zwiększenie bezpieczeństwa typów i mniej rzucania typów w klasach abstrakcyjnych. Jest to odpowiednik
ArrayList
vsList<T>
na większą skalę.źródło