Dlaczego warto użyć słowa kluczowego params?

Wiem, że to podstawowe pytanie, ale nie mogłem znaleźć odpowiedzi.

Dlaczego go używać? jeśli napiszesz funkcję lub metodę, która jej używa, po jej usunięciu kod nadal będzie działał idealnie, w 100% tak, jak bez niego. Np.:

With params:

static public int addTwoEach(params int[] args)
{
    int sum = 0;
    foreach (var item in args)
        sum += item + 2;
    return sum;
}

Bez paramów:

static public int addTwoEach(int[] args)
{
    int sum = 0;
    foreach (var item in args)
       sum += item + 2;
    return sum;
}
Author: MasterMastic, 2011-09-28

7 answers

Z params możesz wywołać swoją metodę w ten sposób:

addTwoEach(1, 2, 3, 4, 5);

Bez params, nie możesz.

Dodatkowo można wywołać metodę z tablicą jako parametrem w obu przypadkach :

addTwoEach(new int[] { 1, 2, 3, 4, 5 });

To znaczy params pozwala na użycie skrótu podczas wywoływania metody.

Niepowiązane, możesz drastycznie skrócić swoją metodę:

public static int addTwoEach(params int[] args)
{
    return args.Sum() + 2 * args.Length;
}
 417
Author: Konrad Rudolph,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-09-28 08:24:23

Użycie params pozwala na wywołanie funkcji bez argumentów. Bez params:

static public int addTwoEach(int[] args)
{
    int sum = 0;

    foreach (var item in args)
    {
        sum += item + 2;
    }

    return sum;
}

addtwoEach(); // throws an error

Porównaj z params:

static public int addTwoEach(params int[] args)
{
    int sum = 0;

    foreach (var item in args)
    {
        sum += item + 2;
    }

    return sum;
}

addtwoEach(); // returns 0

Ogólnie można używać params, gdy liczba argumentów może się różnić od 0 do nieskończoności, i używać tablicy, gdy liczba argumentów zmienia się od 1 do nieskończoności.

 81
Author: Vasya,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-17 06:52:07

Pozwala na dodanie tylu podstawowych parametrów w wywołaniu, ile chcesz.

addTwoEach(10, 2, 4, 6)

Natomiast w drugiej postaci musisz użyć tablicy jako parametru

addTwoEach(new int[] {10,2,4,6})
 17
Author: okrumnow,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-09-28 08:26:06

Jednym z zagrożeń ze słowem kluczowym params jest, jeśli po wywołania metody zostały zakodowane,

  1. ktoś przypadkowo / celowo usuwa jeden / więcej wymaganych parametrów z podpisu metody, oraz
  2. jeden/więcej wymagane parametry bezpośrednio przed parametrem params przed zmianą podpisu były zgodne z parametrem params,

Te wywołania będą nadal kompilowane z jednym / więcej wyrażeń poprzednio przeznaczone dla wymagane parametry traktowane jako opcjonalny parametr params. Właśnie natrafiłem na najgorszy możliwy przypadek: parametr {[0] } był typu object[].

Jest to godne uwagi, ponieważ programiści są przyzwyczajeni do tego, że kompilator klepie sobie nadgarstki o wiele bardziej powszechnym scenariuszu, w którym parametry są usuwane z metody ze wszystkimi wymaganymi parametrami (ponieważ # oczekiwanych parametrów ulegnie zmianie).

Dla mnie to nie warto iść na skróty. (Type)[] Bez params będzie działać z 0 do nieskończoności # parametrów bez konieczności nadpisywania. Najgorsze jest to, że będziesz musiał dodać , new (Type) [] {} do połączeń, gdzie nie ma zastosowania.

Btw, imho, najbezpieczniejszym (i najbardziej czytelnym ćwiczeniem) jest:

  1. Przechodzimy przez nazwane parametry (co możemy teraz zrobić nawet W C# ~2 dekad po tym jak możemy w VB ;P) (ponieważ:

    1.1. jest to tylko sposób, który gwarantuje zapobieganie niezamierzonym wartościom przekazywanym do parametrów po zmianie kolejności parametrów, zgodnego typu i/lub liczby po zakodowaniu wywołań,

    1.2. to zmniejsza te szanse po zmianie znaczenia parametru, ponieważ prawdopodobna nowa nazwa identyfikatora odzwierciedlająca nowe znaczenie jest tuż obok przekazywanej do niego wartości,

    1.3. pozwala to uniknąć konieczności liczenia przecinków i przeskakiwania w przód iw tył od wywołania do podpisu, aby zobaczyć, jakie wyrażenie jest przekazywane do jakiego parametru, oraz

    1.4. jeśli musisz użyć opcjonalnych parametrów (params lub nie), pozwala to na wyszukiwanie wywołań, w których przekazywany jest konkretny opcjonalny parametr (a zatem najprawdopodobniej nie jest lub przynajmniej ma możliwość nie być wartością domyślną),

    (uwaga: powody 1.2. i 1.3. może złagodzić i zmniejszyć ryzyko błędu nawet przy kodowaniu początkowych połączeń, nie wspominając o tym, gdy połączenia muszą być odczytywane i / lub zmieniane.))

I

  1. Zrób tak jeden - Parametr-PER-LINE dla lepszej czytelności (ponieważ:

    2.1. jest mniej zaśmiecony i

    2.2. pozwala to uniknąć konieczności przewijania w prawo i w lewo (i konieczności to zrobić na linii, ponieważ większość śmiertelników nie może odczytać lewej części wielu linii, przewijać w prawo i czytać prawą część)).

Uwaga :

  1. Przekazywanie zmiennych, których nazwy odzwierciedlają parametry ' nie pomaga, gdy:

    1.1. przechodzisz dosłownie Stałe (np. proste 0/1 lub prawda / fałsz, które nawet "'najlepsze praktyki '" mogą nie wymagać użycia nazwanych stałych, a ich cel nie może być łatwo wywnioskowany z nazwy metody),

    1.2. metoda jest znacznie niższego poziomu / bardziej ogólna niż wywołujący, tak że nie chcesz / być w stanie nazwać swoich zmiennych tak samo / podobnie do parametrów (lub odwrotnie), lub

    1.3. ponownie zamawiasz / wymieniasz parametry w podpisie, które mogą skutkować wcześniejszymi połączeniami wciąż Kompiluję, ponieważ typy stają się nadal kompatybilne.

  2. Posiadanie funkcji automatycznego zawijania, takiej jak VS, eliminuje tylko jeden (#2.2) z 6 powodów, które podałem powyżej. Do końca 2015 roku nie było auto-wcięcia (!?! Naprawdę, pani?!?), co zwiększa powagę rozumu #2.1.

VS powinien mieć opcję generującą urywki wywołania metody z nazwanymi parametrami (po jednym na linię oczywiście ;P) oraz opcję kompilatora, która wymaga nazwanych parametrów (podobne w koncepcji do opcji Explicit w VB, które, btw, Wymaganie było kiedyś uważane za równie skandaliczne, ale teraz jest proly wymagane przez "'Best Practices'"). W rzeczywistości, "back in my day";), w 1991 zaledwie kilka miesięcy w mojej karierze, jeszcze zanim używałem (lub nawet widziałem) język z nazwanymi parametrami, miałem anty-sheeple / "just Boz you can, don' t mean you should "/ don 't blindly" cut the ends of the roast " sense wystarczy, aby to zasymulować (używając komentarzy in-line), nie widząc nikogo, kto to robi. Brak konieczności używania nazwanych parametrów (jak również innych składni zapisujących"' cenne '"' naciśnięcia klawiszy kodu źródłowego) jest reliktem ery kart dziurkowanych, kiedy zaczęła się większość tych składni. Nie ma na to usprawiedliwienia z nowoczesnym sprzętem, IDE i znacznie bardziej złożonym oprogramowaniem, w którym czytelność jest dużo, dużo, dużo ważniejsza. "Kod czyta się znacznie częściej niż jest zapisywany". Dopóki nie powielasz nie-automatycznie aktualizowany kod, każde zapisane naciśnięcie klawisza może kosztować wykładniczo więcej, gdy ktoś (nawet ty) próbuje go odczytać później.

 11
Author: Tom,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-09 17:46:58

Nie ma potrzeby tworzenia metod przeciążania, wystarczy użyć jednej metody z param jak pokazano poniżej

// Call params method with one to four integer constant parameters.
//
int sum0 = addTwoEach();
int sum1 = addTwoEach(1);
int sum2 = addTwoEach(1, 2);
int sum3 = addTwoEach(3, 3, 3);
int sum4 = addTwoEach(2, 2, 2, 2);
 8
Author: electricalbah,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-17 06:53:28

params pozwala również na wywołanie metody z jednym argumentem.

private static int Foo(params int[] args) {
    int retVal = 0;
    Array.ForEach(args, (i) => retVal += i);
    return retVal;
}

Czyli Foo(1); zamiast Foo(new int[] { 1 });. Może być użyteczny dla skrótów w scenariuszach, w których może być konieczne podanie jednej wartości, a nie całej tablicy. Nadal jest traktowany w ten sam sposób w metodzie, ale daje trochę słodyczy za wywołanie w ten sposób.

 4
Author: David Anderson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-09-28 08:55:44

Dodanie samego słowa kluczowego params pokazuje, że można przekazać wiele liczb parametrów podczas wywołania tej metody, co nie jest możliwe bez jej użycia. Dokładniej:

static public int addTwoEach(params int[] args)
{
    int sum = 0;

    foreach (var item in args)
    {
        sum += item + 2;
    }

    return sum;
}

Gdy wywołasz powyższą metodę, możesz ją wywołać dowolną z następujących metod:

  1. addTwoEach()
  2. addTwoEach(1)
  3. addTwoEach(new int[]{ 1, 2, 3, 4 })

Ale kiedy usuniesz słowo kluczowe params tylko trzecia droga z powyższych sposobów będzie działać dobrze. W przypadku 1. i 2. otrzymasz błąd.

 4
Author: Ashwini,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-16 14:48:11