W moim obecnym projekcie spotkałem się z wymogiem tworzenia klas ogólnych o tej samej nazwie, ale o różnej liczbie parametrów ogólnych. Na przykład:
MyClass<T1>
MyClass<T1, T2>
MyClass<T1, T2, T3>
Biorąc pod uwagę, że chcę je wszystkie w tej samej przestrzeni nazw, nie jestem pewien, jak ustrukturyzować i nazwać moje klasy i pliki?
Jeśli podążamy za ideą, że powinniśmy mieć klasy ograniczone do jednej na plik, a pliki powinny mieć strukturę folderów reprezentującą hierarchię przestrzeni nazw i że nazwa pliku powinna pasować do nazwy klasy, jak poradzić sobie z tą sytuacją ?
Naprawdę pytam o to, jak powinienem nazwać plik zawierający MyClass<T1>
i co powinienem nazwać plik zawierający MyClass<T1, T2>
? Nie pytam, jakie powinny być nazwy parametrów typu.
TKey, TValue
konwencję. Func maTResult
parametr typu. Choć zgadzam się, że można użyćT1
,T2
itp dla zmiennej liczby parametrów wejściowych, które inaczej nie mają szczególnych zastosowań jakTKey
iTValue
.Odpowiedzi:
I tak dalej, gdzie liczba po znaku wstecz jest liczbą parametrów typu ogólnego. Ta konwencja jest używana przez Microsoft.
Alternatywnie możesz użyć czegoś takiego
która zachowuje nie tylko liczbę ogólnych parametrów typu, ale także ich specyficzne nazwy. To prawda, że nie zachowuje nawiasów kątowych, ale nie możemy mieć wszystkiego w życiu, czego chcemy, prawda?
źródło
W przypadku
Tuple
iAction
że Pete wspomniał, Microsoft sami użyć pojedynczego pliku - patrz Tuple.cs i Action.cs .Myślę, że częściowo zależy to od tego, czy funkcjonalność wszystkich klas jest zasadniczo taka sama. Osobiście nie lubię grupować klas w jeden plik, ale może to być wyjątek. W kodzie źródłowym, w którym pracuję, dodałem automatycznie generowaną (za pomocą T4)
NamedTuple
klasę, która działa w taki sam sposóbTuple
, ale z nazwą łańcucha jako pierwszym argumentem w konstruktorze.Aby odpowiedzieć na pytanie, jeśli nie chcesz używać jednego pliku, być może użyj MyClass_1.cs dla
MyClass<T1>
, MyClass_2.cs dlaMyClass<T1, T2>
itp.Żadna z tych opcji nie jest jednak idealna, dlatego chętnie zasugeruję argument „Microsoft zrób to w ten sposób, więc ...”.
źródło
Tuple
iAction
wszyscy są delegatami; nie mają żadnego kodu implementacji, więc umieszczenie wszystkich odmian w osobnych plikach i tak byłoby trochę bezcelowe. Udowadnia tylko, że każda reguła ma wyjątek.Tuple
nie jest delegatem, ale i tak każda implementacja jest krótka.Func
.Czy zadawałeś sobie pytanie, czy zajęcia mają taki sam cel? Jeśli jedna klasa jest bardziej ogólna od drugiej, będzie to GenericClass , MoreGenericClass i MostGenericClass . Wyobraź sobie, że każdy parametr typu klasy dodaje nowy wymiar do klasy, więc może pomóc pytanie, jaki to wymiar.
Weźmy ten przykład:
Container<Thing>
MetricContainer<Thing, Metric>
MetricTransportableContainer<Thing, Metric, Transport>
Wiem, że nie jest to najlepszy przykład, ale bardzo ekspresyjny, aby pokazać trzy wymiary:
Możesz więc modelować transport samochodów:
Transport płynów:
Transport energii:
Transport cukru, zbóż:
Och, co za niespodzianka: a
List<T>
ma jeden wymiar, który reprezentuje rzeczy, które może pomieścić lista; i jest toMap<T, S>
z dwoma wymiarami, które reprezentują rzeczy, które może pomieścić mapa i klucze dostępu.źródło
Tuple<T1>
,Tuple<T1, T2>
aTuple<T1, T2, T3>
na oddzielne pliki CS w standardowy sposób, bez nazwy starć?