Projekt parametrów

Uwaga

Ta zawartość jest drukowana przez uprawnienie Pearson Education, Inc. z Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries, 2nd Edition. Wydanie to zostało opublikowane w 2008 roku, a książka została w pełni zmieniona w trzecim wydaniu. Niektóre informacje na tej stronie mogą być nieaktualne.

Ta sekcja zawiera szerokie wytyczne dotyczące projektowania parametrów, w tym sekcje z wytycznymi dotyczącymi sprawdzania argumentów. Ponadto należy zapoznać się z wytycznymi opisanymi w temacie Naming Parameters (Parametry nazewnictwa).

✔️ Należy użyć najmniej pochodnego typu parametru, który zapewnia funkcjonalność wymaganą przez element członkowski.

Załóżmy na przykład, że chcesz zaprojektować metodę, która wylicza kolekcję i drukuje każdy element w konsoli. Taka metoda powinna przyjmować IEnumerable jako parametr, a nie ArrayList lub IList, na przykład.

❌ NIE UŻYWAJ parametrów zarezerwowanych.

Jeśli w niektórych przyszłych wersjach będzie potrzebnych więcej danych wejściowych do elementu członkowskiego, można dodać nowe przeciążenie.

❌ NIE mają publicznie uwidocznionych metod, które przyjmują wskaźniki, tablice wskaźników lub tablic wielowymiarowych jako parametry.

Wskaźniki i tablice wielowymiarowe są stosunkowo trudne do prawidłowego użycia. W prawie wszystkich przypadkach interfejsy API można przeprojektować, aby uniknąć podejmowania tych typów jako parametrów.

✔️ Umieść wszystkie out parametry zgodnie ze wszystkimi parametrami według wartości i ref parametrów (z wyłączeniem tablic parametrów), nawet jeśli powoduje niespójność w kolejności parametrów między przeciążeniami (zobacz Przeciążenie składowe).

out Parametry mogą być postrzegane jako dodatkowe wartości zwracane i grupowanie ich razem sprawia, że sygnatura metody jest łatwiej zrozumieć.

✔️ Należy zachować spójność parametrów nazewnictwa podczas zastępowania elementów członkowskich lub implementowania elementów członkowskich interfejsu.

Dzięki temu lepiej komunikuje się relacja między metodami.

Wybieranie między parametrami wyliczeniowymi i logicznymi

✔️ Należy użyć wyliczenia, jeśli element członkowski w przeciwnym razie ma dwa lub więcej parametrów logicznych.

❌ NIE należy używać wartości logicznych, chyba że jest absolutnie pewien, że nigdy nie będzie potrzeby więcej niż dwóch wartości.

Wyliczenia zapewniają trochę miejsca na przyszłe dodawanie wartości, ale należy pamiętać o wszystkich implikacjach dodawania wartości do wyliczenia, które opisano w projekcie wyliczenia.

✔️ ROZWAŻ użycie wartości logicznych dla parametrów konstruktora, które są naprawdę wartościami dwustanowymi i są po prostu używane do inicjowania właściwości logicznych.

Weryfikowanie argumentów

✔️ Czy weryfikować argumenty przekazywane do publicznych, chronionych lub jawnie zaimplementowanych elementów członkowskich. Wyrzuć System.ArgumentExceptionelement lub jedną z jego podklas, jeśli walidacja zakończy się niepowodzeniem.

Należy pamiętać, że rzeczywista walidacja nie musi odbywać się w samym publicznym lub chronionym elemencie członkowskim. Może się to zdarzyć na niższym poziomie w niektórych prywatnych lub wewnętrznych rutynowych. Głównym punktem jest to, że cały obszar powierzchni uwidoczniony dla użytkowników końcowych sprawdza argumenty.

✔️ Wyrzuć, ArgumentNullException jeśli argument null jest przekazywany, a element członkowski nie obsługuje argumentów null.

✔️ Zweryfikuj parametry wyliczenia.

Nie zakładaj, że argumenty wyliczenia będą znajdować się w zakresie zdefiniowanym przez wyliczenie. ClR umożliwia rzutowanie dowolnej wartości całkowitej do wartości wyliczeniowej, nawet jeśli wartość nie jest zdefiniowana w wyliczeniem.

❌ NIE NALEŻY używać Enum.IsDefined do sprawdzania zakresu wyliczenia.

✔️ Należy pamiętać, że argumenty modyfikowalne mogły ulec zmianie po ich zweryfikowaniu.

Jeśli element członkowski jest poufny w zabezpieczeniach, zachęcamy do utworzenia kopii, a następnie zweryfikowania i przetworzenia argumentu.

Przekazywanie parametru

Z perspektywy projektanta platformy istnieją trzy główne grupy parametrów: parametry według wartości, ref parametry i out parametry.

Gdy argument jest przekazywany przez parametr by-value, element członkowski otrzymuje kopię rzeczywistego argumentu przekazanego. Jeśli argument jest typem wartości, kopia argumentu zostanie umieszczona na stosie. Jeśli argument jest typem odwołania, kopia odwołania jest umieszczana na stosie. Najpopularniejsze języki CLR, takie jak C#, VB.NET i C++, domyślnie przekazują parametry według wartości.

Gdy argument jest przekazywany przez ref parametr, element członkowski otrzymuje odwołanie do rzeczywistego argumentu przekazanego. Jeśli argument jest typem wartości, odwołanie do argumentu jest umieszczane na stosie. Jeśli argument jest typem odwołania, odwołanie do odwołania jest umieszczane na stosie. Ref Parametry mogą służyć do zezwalania członkowi na modyfikowanie argumentów przekazywanych przez obiekt wywołujący.

Out parametry są podobne do ref parametrów z niewielkimi różnicami. Parametr jest początkowo uznawany za nieprzypisany i nie można go odczytać w treści elementu członkowskiego, zanim zostanie przypisana pewna wartość. Ponadto parametr musi być przypisany do pewnej wartości przed zwróceniem elementu członkowskiego.

❌ UNIKAJ używania out parametrów lub ref .

Używanie out parametrów lub ref wymaga doświadczenia ze wskaźnikami, zrozumienia różnic typów wartości i typów odwołań oraz obsługi metod z wieloma wartościami zwracanymi. Ponadto różnica między parametrami out i ref nie jest powszechnie rozumiana. Architekci struktury projektujący dla odbiorców ogólnych nie powinni oczekiwać, że użytkownicy będą biegłi w pracy z parametrami out lub ref .

❌ NIE przekazuj typów odwołań według odwołania.

Istnieją pewne ograniczone wyjątki reguły, takie jak metoda, która może służyć do zamiany odwołań.

Elementy członkowskie ze zmienną liczbą parametrów

Elementy członkowskie, które mogą przyjmować zmienną liczbę argumentów, są wyrażane przez podanie parametru tablicy. Na przykład String udostępnia następującą metodę:

public class String {
    public static string Format(string format, object[] parameters);
}

Następnie użytkownik może wywołać metodę String.Format w następujący sposób:

String.Format("File {0} not found in {1}",new object[]{filename,directory});

Dodanie słowa kluczowego params języka C# do parametru tablicy zmienia parametr na tak zwany parametr tablicy params i udostępnia skrót do tworzenia tablicy tymczasowej.

public class String {
    public static string Format(string format, params object[] parameters);
}

Dzięki temu użytkownik może wywołać metodę, przekazując elementy tablicy bezpośrednio na liście argumentów.

String.Format("File {0} not found in {1}",filename,directory);

Należy pamiętać, że słowo kluczowe params można dodać tylko do ostatniego parametru na liście parametrów.

✔️ ROZWAŻ dodanie słowa kluczowego params do parametrów tablicy, jeśli oczekujesz, że użytkownicy końcowi przekażą tablice z niewielką liczbą elementów. Jeśli oczekuje się, że wiele elementów zostanie przekazanych w typowych scenariuszach, użytkownicy prawdopodobnie nie przekażą tych elementów w tekście i tak, więc słowo kluczowe params nie jest konieczne.

❌ UNIKAJ używania tablic params, jeśli obiekt wywołujący prawie zawsze będzie miał dane wejściowe już w tablicy.

Na przykład składowe z parametrami tablicy bajtów prawie nigdy nie będą wywoływane przez przekazanie poszczególnych bajtów. Z tego powodu parametry tablicy bajtów w programie .NET Framework nie używają słowa kluczowego params.

❌ NIE należy używać tablic params, jeśli tablica jest modyfikowana przez element członkowski biorąc parametr tablicy params.

Ze względu na fakt, że wiele kompilatorów zamienia argumenty na składową w tablicę tymczasową w lokacji wywołania, tablica może być obiektem tymczasowym, dlatego wszelkie modyfikacje tablicy zostaną utracone.

✔️ ROZWAŻ użycie słowa kluczowego params w prostym przeciążeniu, nawet jeśli bardziej złożone przeciążenie nie może go używać.

Zadaj sobie pytanie, czy użytkownicy mają tablicę params w jednym przeciążeniu, nawet jeśli nie było we wszystkich przeciążeniach.

✔️ Spróbuj zamówić parametry, aby umożliwić użycie słowa kluczowego params.

✔️ ROZWAŻ zapewnienie specjalnych przeciążeń i ścieżek kodu dla wywołań z niewielką liczbą argumentów w bardzo wrażliwych na wydajność interfejsach API.

Dzięki temu można uniknąć tworzenia obiektów tablicowych, gdy interfejs API jest wywoływany z niewielką liczbą argumentów. Utwórz nazwy parametrów, przyjmując pojedynczą formę parametru tablicy i dodając sufiks liczbowy.

Należy to zrobić tylko wtedy, gdy zamierzasz utworzyć całą ścieżkę kodu, a nie tylko utworzyć tablicę i wywołać bardziej ogólną metodę.

✔️ Należy pamiętać, że wartość null może zostać przekazana jako argument tablicy params.

Przed przetworzeniem należy sprawdzić, czy tablica nie ma wartości null.

❌ NIE należy używać varargs metod, inaczej znanych jako wielokropek.

Niektóre języki CLR, takie jak C++, obsługują alternatywną konwencję przekazywania list parametrów zmiennych nazywanych varargs metodami. Konwencja nie powinna być używana w strukturach, ponieważ nie jest zgodna ze specyfikacją CLS.

Parametry wskaźnika

Ogólnie rzecz biorąc, wskaźniki nie powinny pojawiać się w obszarze powierzchni publicznej dobrze zaprojektowanej struktury kodu zarządzanego. W większości przypadków wskaźniki powinny być hermetyzowane. Jednak w niektórych przypadkach wskaźniki są wymagane ze względów współdziałania, a użycie wskaźników w takich przypadkach jest odpowiednie.

✔️ Funkcja DO zapewnia alternatywę dla każdego elementu członkowskiego, który przyjmuje argument wskaźnika, ponieważ wskaźniki nie są zgodne ze specyfikacją CLS.

❌ UNIKAJ wykonywania kosztownego sprawdzania argumentów wskaźnika.

✔️ Należy przestrzegać typowych konwencji związanych ze wskaźnikiem podczas projektowania elementów członkowskich ze wskaźnikami.

Na przykład nie ma potrzeby przekazywania indeksu początkowego, ponieważ proste arytmetyka wskaźnika może służyć do osiągnięcia tego samego wyniku.

© Części 2005, 2009 Microsoft Corporation. Wszelkie prawa zastrzeżone.

Reprinted by permission of Pearson Education, Inc. from Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries, 2nd Edition by Krzysztof Cwalina and Brad Abrams, published oct 22, 2008 by Addison-Wesley Professional w ramach Microsoft Windows Development Series.

Zobacz też