Uwaga: To pytanie zostało zadane w czasie, gdy C # nie obsługiwał jeszcze parametrów opcjonalnych (tj. Przed C # 4).
Budujemy internetowy interfejs API generowany programowo z klasy C #. Klasa ma metodę, GetFooBar(int a, int b)
a API ma metodę GetFooBar
przyjmującą parametry zapytania, takie jak &a=foo &b=bar
.
Klasy muszą obsługiwać parametry opcjonalne, które nie są obsługiwane w języku C #. Jakie jest najlepsze podejście?
c#
optional-parameters
Kalid
źródło
źródło
Odpowiedzi:
Zaskoczony, nikt nie wspomniał o opcjonalnych parametrach C # 4.0, które działają w ten sposób:
Edycja: Wiem, że w momencie zadawania pytania C # 4.0 nie istniało. Ale to pytanie wciąż zajmuje pierwsze miejsce w Google pod względem „opcjonalnych argumentów w języku C #”, więc pomyślałem - tę odpowiedź warto tu znaleźć. Przepraszam.
źródło
Inną opcją jest użycie słowa kluczowego params
Nazywany jak ...
źródło
public void log (params object[] args){ StringBuilder sb = new StringBuilder(); for (int i = 0; i < args.Length; i++){ sb.Append("{"); sb.Append(i.ToString()); sb.Append("}"); sb.Append(" "); } String.Format(sb.ToString(),args).Dump(); }
Przykładowe wywołanie:log("...Done,",(watch.ElapsedMilliseconds/1000).ToString(),"s");
W języku C # normalnie użyłbym wielu form tej metody:
AKTUALIZACJA: Wspomniałem powyżej, był sposób, w jaki zrobiłem wartości domyślne z C # 2.0. Projekty, nad którymi teraz pracuję, używają C # 4.0, który teraz bezpośrednio obsługuje parametry opcjonalne. Oto przykład, którego właśnie użyłem we własnym kodzie:
źródło
Z tej strony:
http://www.tek-tips.com/viewthread.cfm?qid=1500861&page=1
C # pozwala na użycie atrybutu [Opcjonalnie] (z VB, choć nie działa w C #). Możesz mieć taką metodę:
W naszym opakowaniu API wykrywamy parametry opcjonalne (ParameterInfo p.IsOptional) i ustawiamy wartość domyślną. Celem jest oznaczenie parametrów jako opcjonalne bez uciekania się do klaudges, takich jak „opcjonalne” w nazwie parametru.
źródło
Możesz użyć przeciążenia metody ...
Zależy to od sygnatur metody, w podanym przykładzie brakuje metody „int b”, ponieważ miałaby taką samą sygnaturę jak metoda „int a”.
Możesz użyć typów dopuszczających wartości zerowe ...
Następnie możesz sprawdzić za pomocą a.HasValue, czy parametr został ustawiony.
Inną opcją byłoby użycie parametru „params”.
Jeśli chcesz użyć nazwanych parametrów, musisz utworzyć typ do ich obsługi, chociaż myślę, że jest już coś takiego dla aplikacji internetowych.
źródło
Możesz używać opcjonalnych parametrów w C # 4.0 bez żadnych obaw. Jeśli mamy metodę taką jak:
podczas wywoływania metody można pominąć parametry takie jak to:
C # 4.0 implementuje funkcję zwaną „nazwanymi parametrami”, możesz faktycznie przekazywać parametry według ich nazw i oczywiście możesz przekazywać parametry w dowolnej kolejności :)
źródło
Witaj, opcjonalny świecie
Jeśli środowisko wykonawcze ma podawać domyślną wartość parametru, należy użyć odbicia, aby wykonać połączenie. Nie tak ładne, jak inne sugestie dotyczące tego pytania, ale zgodne z VB.NET.
źródło
Prostym sposobem, który pozwala pominąć dowolne parametry w dowolnej pozycji , jest wykorzystanie typów zerowalnych w następujący sposób:
Ciągi są już typami zerowalnymi, więc nie potrzebują ? .
Po uzyskaniu tej metody wszystkie wywołania są prawidłowe :
Kiedy definiujesz metodę w ten sposób, możesz dowolnie ustawiać tylko te parametry, które chcesz nazwać . Zobacz poniższy link, aby uzyskać więcej informacji na temat nazwanych i opcjonalnych parametrów:
Argumenty nazwane i opcjonalne (Podręcznik programowania w języku C #) @ MSDN
źródło
Zgadzam się ze Stephenbayerem. Ponieważ jednak jest to usługa internetowa, użytkownikowi końcowemu łatwiej jest użyć tylko jednej formy metody internetowej niż wielu wersji tej samej metody. Myślę, że w tej sytuacji typy dopuszczające wartości zerowe są idealne dla parametrów opcjonalnych.
źródło
parametry opcjonalne dotyczą metod. jeśli potrzebujesz opcjonalnych argumentów dla klasy i jesteś:
za pomocą c # 4.0: użyj opcjonalnych argumentów w konstruktorze klasy, rozwiązanie to preferuję, ponieważ jest bliżej tego, co jest zrobione metodami, więc łatwiej je zapamiętać. oto przykład:
używając wersji c # wcześniejszych niż c # 4.0: powinieneś użyć łączenia konstruktorów (używając słowa kluczowego:), gdzie prostsze konstruktory prowadzą do „głównego konstruktora”. przykład:
źródło
Typowym sposobem, w jaki jest to obsługiwane w języku C #, jak wspomniano Stephen, jest przeciążenie metody. Tworząc wiele wersji metody z różnymi parametrami, skutecznie tworzysz parametry opcjonalne. W formularzach z mniejszą liczbą parametrów zwykle wywołujesz formę metody, a wszystkie parametry ustawiają wartości domyślne w wywołaniu tej metody.
źródło
Możesz przeładować swoją metodę. Jedna metoda zawiera jeden parametr,
GetFooBar(int a)
a drugi oba parametry,GetFooBar(int a, int b)
źródło
Korzystanie z przeciążeń lub przy użyciu C # 4.0 lub nowszej
źródło
W przypadku większej liczby parametrów opcjonalnych można użyć jednego parametru Dictionary z metodą ContainsKey. Podoba mi się to podejście, ponieważ pozwala mi przekazywać Listę lub T indywidualnie bez konieczności tworzenia całej innej metody (fajnie, jeśli na przykład parametry mają być używane jako filtry).
Przykład (nowy słownik <ciąg, obiekt> () zostałby przekazany, jeśli nie są wymagane żadne parametry opcjonalne):
źródło
Zamiast parametrów domyślnych, dlaczego nie zbudować klasy słownika z przekazanego kwerendy .. implementacja, która jest prawie identyczna ze sposobem, w jaki formularze asp.net działają z kwerendami.
tj. Request.QueryString [„a”]
To oddzieli klasę skrzydła od kodu fabrycznego / kodu płyty kotłowej.
Możesz także chcieć sprawdzić usługi sieciowe za pomocą ASP.NET . Usługi sieciowe to API generowane automatycznie przez atrybuty klas C #.
źródło
Trochę późno na imprezę, ale szukałem odpowiedzi na to pytanie i ostatecznie wymyśliłem inny sposób na zrobienie tego. Zadeklaruj typy danych dla opcjonalnych argumentów metody internetowej, aby były typu XmlNode. Jeśli opcjonalny arg zostanie pominięty, zostanie ustawiony na null, a jeśli jest obecny, można uzyskać wartość ciągu, wywołując arg.Value, tj.
Przyzwoite w tym podejściu jest również to, że strona główna wygenerowana w .NET dla WS nadal pokazuje listę argumentów (choć tracisz przydatne pola do wprowadzania tekstu do testowania).
źródło
Mam do napisania usługę internetową, która zajmuje 7 parametrów. Każda z nich jest opcjonalnym atrybutem zapytania do instrukcji SQL zapakowanej przez tę usługę internetową. Tak więc przychodzą mi na myśl dwa obejścia nie opcjonalnych parametrów ... oba dość słabe:
metoda 1 (param1, para2, para 3, para 4, para 5, para 6, para 7) metoda 1 (para 1, para 2, para 3, para 4, para 5, para 6) metoda 1 (para 1, para 2, para 3, para 4, para 5, para 7 ) ... zacznij widzieć obraz. W ten sposób leży szaleństwo. Zbyt wiele kombinacji.
Teraz dla prostszego sposobu, który wygląda niezręcznie, ale powinien działać: method1 (param1, bool useParam1, param2, bool useParam2 itp.)
Jest to jedno wywołanie metody, wymagane są wartości dla wszystkich parametrów i będzie on obsługiwał każdy przypadek wewnątrz niego. Jest również jasne, jak go używać z interfejsu.
To hack, ale zadziała.
źródło
Musiałem to zrobić w serwisie internetowym VB.Net 2.0. W końcu podałem parametry jako ciągi, a następnie przekonwertowałem je na wszystko, czego potrzebowałem. Opcjonalny parametr został określony z pustym ciągiem. Nie najczystsze rozwiązanie, ale zadziałało. Uważaj tylko, aby uchwycić wszystkie wyjątki, które mogą wystąpić.
źródło
Na wszelki wypadek, jeśli ktoś chce przekazać callback (lub
delegate
) jako parametr opcjonalny, może to zrobić w ten sposób.Opcjonalny parametr wywołania zwrotnego:
źródło
parametry opcjonalne są niczym innym jak parametrami domyślnymi! sugeruję, aby podać oba parametry domyślne. GetFooBar (int a = 0, int b = 0), jeśli nie masz żadnej przeciążonej metody, spowoduje a = 0, b = 0, jeśli nie podasz żadnych wartości, jeśli podasz 1 wartość, spowoduje , przekazał wartość dla a, 0, a jeśli przekażesz 2 wartości, 1. zostanie przypisane do a, a drugie do b.
mam nadzieję, że odpowiada na twoje pytanie.
źródło
W przypadku, gdy wartości domyślne nie są dostępne, sposobem dodania parametru opcjonalnego jest użycie klasy .NET OptionalAttribute - https://docs.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.optionalattribute ? widok = netframework-4.8
Przykład kodu znajduje się poniżej:
źródło
Możesz tego także spróbować
Typ 1
public void YourMethod(int a=0, int b = 0) { //some code }
Wpisz 2
public void YourMethod(int? a, int? b) { //some code }
źródło