web-dev-qa-db-fra.com

Pourquoi utiliser le mot clé params?

Je sais que c'est une question fondamentale, mais je n'ai pas trouvé de réponse.

Pourquoi l'utiliser? si vous écrivez une fonction ou une méthode qui l'utilise, lorsque vous la supprimez, le code fonctionnera toujours parfaitement, à 100% comme sans elle. Par exemple:

avec params:

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

sans paramètres:

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

Avec params vous pouvez appeler votre méthode comme suit:

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

Sans params, vous ne pouvez pas.

De plus, vous pouvez appeler la méthode avec un tableau en tant que paramètre dans les deux cas :

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

En d'autres termes, params vous permet d'utiliser un raccourci lorsque vous appelez la méthode.

Sans lien, vous pouvez considérablement raccourcir votre méthode:

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

Utiliser params vous permet d’appeler la fonction sans argument. Sans params:

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

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

    return sum;
}

addtwoEach(); // throws an error

Comparez avec params:

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

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

    return sum;
}

addtwoEach(); // returns 0

En règle générale, vous pouvez utiliser les paramètres lorsque le nombre d'arguments peut varier de 0 à l'infini et utiliser un tableau lorsque le nombre d'arguments varie de 1 à l'infini.

90
Vasya

Il vous permet d’ajouter autant de paramètres de type de base que vous le souhaitez dans votre appel.

addTwoEach(10, 2, 4, 6)

alors qu'avec le second formulaire, vous devez utiliser un tableau comme paramètre

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

Un danger avec params Le mot-clé est, si après les appels à la méthode ont été codés,

  1. une personne supprime accidentellement/intentionnellement un/plusieurs paramètres requis de la signature de méthode, et
  2. one/more required Les paramètres immédiatement avant le paramètre params avant le changement de signature étaient compatibles avec le paramètre params. ,

ces appels continueront à être compilés avec une/plusieurs expressions précédemment destinées à requis Paramètres traités comme le paramètre facultatif params. Je viens de rencontrer le pire cas possible: le paramètre params était de type object[].

Ceci est remarquable car les développeurs sont habitués à ce que le compilateur frappe leurs poignets avec le scénario beaucoup plus courant dans lequel les paramètres sont supprimés d'une méthode avec tous requis Paramètres (car le nombre de paramètres attendus changerait).

Pour moi, ça ne vaut pas le raccourci. (Type)[] sans params fonctionnera avec 0 à l'infini. # De paramètres sans nécessiter de dérogation. Dans le pire des cas, vous devrez ajouter un , new (Type) [] {} aux appels où il ne s'applique pas.

Au fait, à mon humble avis, la pratique la plus sûre (et la plus lisible) consiste à:

  1. passer via les paramètres nommés (que nous pouvons maintenant faire même en C # ~ 2 décennies après que nous ayons pu dans VB; P) (parce que:

    1.1. c'est la manière seulement qui garantit la prévention des valeurs non intentionnelles transmises aux paramètres après L'ordre des paramètres, le type compatible et/ou le nombre changent après le codage des appels,

    1.2. il réduit ces chances après un changement de signification du paramètre, car le nom probable du nouvel identificateur reflétant le nouveau sens est situé juste à côté de la valeur qui lui est transmise,

    1.3. cela évite de compter les virgules et de basculer d'un appel à l'autre pour voir quelle expression est transmise pour quel paramètre, et

    1.3.1. Soit dit en passant, cette seule raison devrait être abondante (en termes d’éviter les violations fréquentes du principe DRY, sujettes aux erreurs, juste pour lire le code pour ne pas mentionner aussi le modifier il), mais cette raison peut être exponentiellement plus important s’il ya une/plusieurs expressions passées contenant elles-mêmes des virgules, c’est-à-dire des références de tableaux multidimensionnelles ou des appels de fonctions multiparamètres. Dans ce cas, vous ne pourriez même pas utiliser (ce qui, même si vous le pouviez, ajouterait encore une étape supplémentaire par paramètre per Appel de méthode) une fonction Rechercher toutes les occurrences dans une sélection de votre éditeur pour automatiser le comptage par virgule pour vous.

    1.4. si vous devez utiliser des paramètres facultatifs (params ou non), il vous permet de rechercher des appels pour lesquels un paramètre facultatif donné est passé (et par conséquent, le plus probable est que non, ou du moins, la possibilité de ne pas être la valeur par défaut ),

(REMARQUE: les motifs 1.2. Et 1.3. Peuvent faciliter et réduire les risques d'erreur, même lors du codage des appels initiaux, sans mentionner le moment où les appels doivent être lus et/ou modifiés.))

et

  1. faire ONE - PARAMETER - PER - LINE pour une meilleure lisibilité (car:

    2.1. c'est moins encombré, et

    2.2. cela évite d'avoir à faire défiler à droite et à gauche (et à faire PER-LINE, car la plupart des mortels ne peuvent pas lire la partie gauche de plusieurs lignes, faire défiler vers la droite et lire la partie droite)).

    2.3. cela correspond à la "meilleure pratique" que nous avons déjà adoptée pour les instructions d'assignation, car chaque paramètre transmis est essentiellement une instruction d'assignation (attribution d'une valeur ou d'une référence à une variable locale). Tout comme ceux qui suivent la "meilleure pratique" du style de codage la plus récente ne rêveraient pas de coder plusieurs instructions d'assignation par ligne, nous ne devrions probablement pas ( et ne sera pas une fois "Best Practice" rattraper à mon "génie"; P) le faire lors de Passing Parameters.

NOTES:

  1. Passer des variables dont les noms sont identiques à ceux des paramètres n'aide pas lorsque:

    1.1. vous transmettez des constantes littérales (c'est-à-dire un simple 0/1, faux/vrai ou nul pour lequel même les "" meilleures pratiques "" ne nécessitent pas nécessairement l'utilisation d'une constante nommée et leur objectif ne peut pas être facilement déduit du nom de la méthode ),

    1.2. la méthode est de niveau nettement inférieur/plus générique que l'appelant, de sorte que vous ne voudriez pas/ne pouvez pas nommer vos variables de la même manière/de manière similaire aux paramètres (ou inversement), ou

    1.3. vous réorganisez/remplacez des paramètres dans la signature pouvant entraîner la compilation d'appels antérieurs, car les types sont toujours compatibles .

  2. Le fait d’avoir une fonctionnalité d’enrubannage automatique comme VS n’élimine qu’UNE (# 2.2) des 8 raisons que j’ai données ci-dessus. Avant VS 2015, il n'était PAS auto-indenté (!?! Vraiment, MS?!?), Ce qui augmente la gravité de la raison # 2.1.

Les VS doivent disposer d’une option qui génère des fragments d’appel à la méthode avec des paramètres nommés (un par ligne bien sûr; P) et d’une option de compilation qui nécessite des paramètres nommés (similaires). in concept to Option Explicit in VB dont, en fait, l'exigence de était toujours considérée comme aussi scandaleuse mais est maintenant obligatoire par "'Best Practices'"). En fait, "en arrière mon jour";), en 1991, quelques mois seulement après le début de ma carrière, avant même que j'utilise (ou ai même vu) un langue avec les paramètres nommés, j'ai eu l'anti-mouton/"juste parce que vous pouvez, ne signifie pas que vous devriez"/ne pas aveuglément "couper les extrémités du rôti" sens assez pour le simuler (en utilisant des commentaires en ligne) sans avoir vu quelqu'un le faire. Ne pas avoir à utiliser les paramètres nommés (ainsi que toute autre syntaxe permettant de sauvegarder les frappes de code source "précieuses") est un vestige de l'ère de la carte perforée au début de la plupart de ces syntaxes. Il n’ya aucune excuse pour cela avec du matériel moderne et des IDE et des logiciels beaucoup plus complexes où la lisibilité est beaucoup, beaucoup, BEAUCOUP plus important. "Le code est lu beaucoup plus souvent que ce qui est écrit". Tant que vous ne dupliquez pas un code non mis à jour automatiquement, chaque frappe de touche enregistrée coûtera de manière exponentielle plus cher lorsque quelqu'un (même vous-même) essaiera de le lire plus tard.

16
Tom

Pas besoin de créer des méthodes de surcharge, utilisez simplement une seule méthode avec les paramètres comme indiqué ci-dessous

// 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

L'ajout du mot-clé params lui-même montre que vous pouvez transmettre plusieurs nombres de paramètres tout en appelant cette méthode, ce qui n'est pas possible sans l'utiliser. Pour être plus précis:

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

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

    return sum;
}

Lorsque vous appelez la méthode ci-dessus, vous pouvez l’appeler de l’une des manières suivantes:

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

Mais lorsque vous supprimerez le mot-clé params, seule la troisième méthode des méthodes indiquées ci-dessus fonctionnera correctement. Pour le 1er et 2ème cas, vous obtiendrez une erreur.

5
Ashwini

params vous permet également d'appeler la méthode avec un seul argument.

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

c'est-à-dire Foo(1); au lieu de Foo(new int[] { 1 });. Peut être utile en abrégé dans des scénarios où vous devrez peut-être transmettre une seule valeur plutôt qu'un tableau entier. Il est toujours traité de la même manière dans la méthode, mais donne un bonbon pour appeler de cette façon.

4
David Anderson

Une autre chose importante doit être soulignée. Il vaut mieux utiliser params car il est meilleur pour la performance. Lorsque vous appelez une méthode avec l'argument params et que vous ne lui transmettez rien:

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

appel:

ExampleMethod();

Ensuite, une nouvelle version de .Net Framework effectue cette opération (à partir de .Net Framework 4.6):

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

Cet objet Array.Empty peut être réutilisé ultérieurement par l'infrastructure. Il n'est donc pas nécessaire de procéder à des allocations redondantes. Ces allocations se produiront lorsque vous appelez cette méthode comme ceci:

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