web-dev-qa-db-de.com

Warum das Schlüsselwort params verwenden?

Ich weiß, dass dies eine grundlegende Frage ist, aber ich konnte keine Antwort finden.

Warum es benutzen? Wenn Sie eine Funktion oder Methode schreiben, die sie verwendet, funktioniert der Code beim Entfernen immer noch einwandfrei, 100% wie ohne. Z.B:

Mit params:

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

Ohne Parameter:

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

Mit params können Sie Ihre Methode folgendermaßen aufrufen:

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

Ohne params geht das nicht.

Zusätzlich können Sie die Methode in beiden Fällen mit einem Array als Parameter aufrufen :

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

Das heißt, params ermöglicht es Ihnen, beim Aufrufen der Methode eine Verknüpfung zu verwenden.

Unabhängig davon können Sie Ihre Methode drastisch verkürzen:

public static int addTwoEach(params int[] args)
{
    return args.Sum() + 2 * args.Length;
}
465
Konrad Rudolph

Mit params können Sie die Funktion ohne Argumente aufrufen. Ohne params:

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

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

    return sum;
}

addtwoEach(); // throws an error

Vergleichen Sie mit params:

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

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

    return sum;
}

addtwoEach(); // returns 0

Im Allgemeinen können Sie params verwenden, wenn die Anzahl der Argumente von 0 bis unendlich variieren kann, und ein Array verwenden, wenn die Anzahl der Argumente von 1 bis unendlich variiert.

90
Vasya

Sie können so viele Basistypparameter in Ihren Aufruf einfügen, wie Sie möchten.

addTwoEach(10, 2, 4, 6)

bei der zweiten Form müssen Sie ein Array als Parameter verwenden

addTwoEach(new int[] {10,2,4,6})
22
okrumnow

Eine Gefahr mit dem Schlüsselwort params ist, wenn after Aufrufe der Methode codiert wurden,

  1. jemand versehentlich/absichtlich einen/mehrere Erforderlich Parameter aus der Methodensignatur entfernt, und
  2. ein/mehrere erforderlich Parameter unmittelbar vor dem params Parameter vor der Signaturänderung waren typkompatibel mit dem params Parameter,

diese Aufrufe werden weiterhin mit einem oder mehreren Ausdrücken kompiliert, die zuvor für erforderlich Parameter bestimmt waren, die als optionale params Parameter behandelt werden. Ich bin gerade auf den schlimmsten Fall gestoßen: Der Parameter params hatte den Typ object[].

Dies ist insofern bemerkenswert, als Entwickler es gewohnt sind, dass der Compiler in dem weitaus häufigeren Szenario, in dem Parameter aus einer Methode mit allen Erforderlich Parametern entfernt werden (da sich die erwartete Anzahl von Parametern ändern würde), ihre Handgelenke schlägt.

Für mich ist es die Abkürzung nicht wert. (Type)[] Ohne params funktioniert mit 0 bis unendlich vielen Parametern, ohne dass Überschreibungen erforderlich sind. Im schlimmsten Fall müssen Sie , new (Type) [] {} zu Anrufen hinzufügen, bei denen dies nicht zutrifft.

Übrigens ist es imho am sichersten (und am besten lesbarsten),

  1. über Named Parameters übergeben (was wir jetzt tun können gerade in C # ~ 2 Jahrzehnte nachdem wir in VB; P)) (weil:

    1.1. Dies ist die nur Methode, mit der garantiert ​​verhindert wird, dass unbeabsichtigte Werte an Parameter übergeben werden, nachdem die Parameterreihenfolge, der kompatible Typ und/oder die Anzahl nach der Codierung der Aufrufe geändert wurden.

    1.2. it reduziert ​​diese Chancen nach einer Änderung der Parameterbedeutung, da der neue Bezeichnername, der die neue Bedeutung widerspiegelt, direkt neben dem Wert steht, der an ihn übergeben wird.

    1.3. Es wird vermieden, Kommas zu zählen und von Aufruf zu Signatur vor und zurück zu springen, um zu sehen, welcher Ausdruck für welchen Parameter übergeben wird, und

    1.3.1. Übrigens sollte dieser Grund allein viele (im Hinblick auf die Vermeidung häufiger fehleranfälliger Verstöße gegen das DRY Prinzip nur zu lesen der Code nicht zu erwähnen auch ändern it), aber dieser Grund kann exponentiell wichtiger sein, wenn ein/mehrere Ausdrücke übergeben werden, die selbst Kommas enthalten, dh mehrdimensional Array Refs oder Multi-Parameter Function Calls. In diesem Fall könnten Sie nicht einmal verwenden (was, selbst wenn Sie könnten, immer noch einen zusätzlichen Schritt hinzufügen würde per Parameter per Methodenaufruf) a Finden Sie alle Vorkommen in einer Auswahlfunktion in Ihrem Editor, um die Kommazählung für Sie zu automatisieren.

    1.4. Wenn Sie optionale Parameter verwenden müssen (params oder nicht), können Sie nach Aufrufen suchen, bei denen ein bestimmter optionaler Parameter übergeben wird (und daher höchstwahrscheinlich nicht oder zumindest nicht als Standard festgelegt ist) Wert),

(HINWEIS: Die Gründe 1.2. Und 1.3. Können die Fehlerwahrscheinlichkeit verringern, selbst wenn die ersten Anrufe codiert werden. Ganz zu schweigen davon, wann Anrufe gelesen und/oder geändert werden müssen.)

und

  1. tun Sie dies EIN - PARAMETER - PRO - LINIE für eine bessere Lesbarkeit (weil:

    2.1. es ist weniger überladen und

    2.2. Es wird vermieden, nach rechts und zurück nach links zu scrollen (und dies PER-LINE zu tun, da die meisten Sterblichen den linken Teil mehrerer Zeilen nicht lesen können, scrollen Sie nach rechts und lesen Sie den rechten Teil).

    2.3. Dies steht im Einklang mit der "Best Practice", die wir bereits für Zuweisungsanweisungen entwickelt haben, da jeder übergebene Parameter im Wesentlichen eine Zuweisungsanweisung ist (Zuweisen eines Werts oder einer Referenz zu einer lokalen Variablen). Genau wie diejenigen, die sich an latest ​​"Best Practice" im Coding Style halten, nicht davon träumen würden, mehrere Assignment Statements pro Zeile zu codieren, sollten wir dies wahrscheinlich nicht tun (und werden es auch nicht einmal tun) - holt auf zu meinem "Genie"; P) tun Sie dies, wenn Sie Parameter übergeben.

NOTIZEN :

  1. Die Übergabe von Variablen, deren Namen die Parameter widerspiegeln, hilft nicht, wenn:

    1.1. Sie übergeben Literal Constants (dh eine einfache 0/1, false/true oder null, für die nicht einmal "Best Practices" die Verwendung einer benannten Konstante erfordern und deren Zweck nicht einfach aus dem Methodennamen abgeleitet werden kann ),

    1.2. Die Methode ist wesentlich niedriger/allgemeiner als der Aufrufer, sodass Sie Ihre Variablen nicht gleich/ähnlich wie die Parameter benennen möchten/können (oder umgekehrt), oder

    1.3. Sie können Parameter in der Signatur neu anordnen/ersetzen, die dazu führen können, dass frühere Aufrufe weiterhin kompiliert werden, da die Typen happen weiterhin kompatibel sind.

  2. Mit einer Auto-Wrap-Funktion wie VS wird nur EIN (# 2.2) der 8 oben genannten Gründe beseitigt. Vor VS 2015 hat es NICHT automatisch eingerückt (!?! Wirklich, MS?!?), Was den Schweregrad von Grund # 2.1 erhöht.

VS sollte eine Option haben, die Methodenaufruf-Snippets mit benannten Parametern generiert (natürlich eines pro Zeile; P) und eine Compiler-Option, die erfordert ​​Benannte Parameter (im Konzept ähnlich wie Option Explicit in VB was übrigens die Forderung von prolly einst genauso empörend fand wie jetzt prolly erforderlich von "'Best Practices'"). Tatsächlich "back in mein tag ";), 1991 nur wenige monate in meiner karriere, noch bevor ich eine sprache mit benannten parametern benutzte (oder sogar gesehen hatte), hatte ich das anti-schäfchen /" nur weil du kannst, nicht Das heißt, Sie sollten die Enden des Bratens nicht blind genug abschneiden, um ihn zu simulieren (mithilfe von Inline-Kommentaren), ohne dass jemand dies gesehen hat. Es ist ein Relikt der Punch Card-Ära, als die meisten dieser Syntaxen begannen, keine benannten Parameter zu verwenden (wie auch keine andere Syntax, die "kostbare" "Tastatureingaben im Quellcode speichert). Es gibt keine Entschuldigung dafür mit moderner Hardware und IDE und viel komplexerer Software, bei der die Lesbarkeit sehr viel ist, viel, VIEL wichtiger. "Code wird viel öfter gelesen als geschrieben". Solange Sie keinen nicht automatisch aktualisierten Code duplizieren, ist es wahrscheinlich, dass jeder gespeicherte Tastendruck exponentiell teurer ist, wenn jemand (sogar Sie selbst) versucht, ihn später zu lesen.

16
Tom

Es ist nicht erforderlich, Überladungsmethoden zu erstellen. Verwenden Sie nur eine einzige Methode mit Parametern (siehe unten)

// 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);
9
electricalbah

Das Hinzufügen des Schlüsselworts params selbst zeigt, dass Sie beim Aufrufen dieser Methode mehrere Parameter übergeben können, was ohne die Verwendung dieser Methode nicht möglich ist. Um genauer zu sein:

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

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

    return sum;
}

Wenn Sie die obige Methode aufrufen, haben Sie folgende Möglichkeiten:

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

Wenn Sie jedoch das Schlüsselwort params entfernen, funktioniert nur die dritte der oben angegebenen Möglichkeiten. Für den 1. und 2. Fall erhalten Sie eine Fehlermeldung.

5
Ashwini

Mit params können Sie die Methode auch mit einem einzigen Argument aufrufen.

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

d.h. Foo(1); anstelle von Foo(new int[] { 1 });. Kann in Szenarien hilfreich sein, in denen Sie möglicherweise einen einzelnen Wert anstelle eines gesamten Arrays übergeben müssen. Es wird in der Methode immer noch genauso gehandhabt, aber es gibt ein paar Süßigkeiten für diesen Aufruf.

4
David Anderson

Eine weitere wichtige Sache muss hervorgehoben werden. Es ist besser, params zu verwenden, da dies die Leistung verbessert. Wenn Sie eine Methode mit dem Argument params aufrufen und nichts übergeben:

public void ExampleMethod(params string[] args)
{
// do some stuff
}

anruf:

ExampleMethod();

Dann führt eine neue Version von .Net Framework dies aus (ab .Net Framework 4.6):

ExampleMethod(Array.Empty<string>());

Diese Array.Empty -Objekt kann später vom Framework wiederverwendet werden, sodass keine redundanten Zuordnungen erforderlich sind. Diese Zuordnungen treten auf, wenn Sie diese Methode wie folgt aufrufen:

 ExampleMethod(new string[] {});
0
Beniamin Makal