méthode surcharge vs paramètre optionnel dans C # 4.0 [dupliquer]

cette question a déjà une réponse ici:

lequel est le meilleur? d'un coup d'oeil, le paramètre optionnel semble meilleur (moins de code, moins de documentation XML, etc.), mais pourquoi faire la plupart des MSDN les classes de bibliothèques utilisent la surcharge au lieu des paramètres optionnels?

y a-t-il quelque chose de spécial que vous devez prendre note lorsque vous choisissez d'utiliser le paramètre optionnel (ou la surcharge)?

104
demandé sur Louis Rhys 2010-07-23 12:09:42

11 réponses

un cas de bonne utilisation pour 'paramètres optionnels' en conjonction avec' paramètres nommés ' dans C# 4.0 est qu'il nous présente une alternative élégante à la méthode de surcharge où vous Méthode de surcharge basée sur le nombre de paramètres.

par exemple, dites que vous voulez qu'une méthode foo soit appelée / utilisée comme ceci, foo() , foo(1) , foo(1,2) , foo(1,2, "hello") . Avec la méthode overloading vous mettriez en œuvre la solution comme ceci,

///Base foo method
public void DoFoo(int a, long b, string c)
{
   //Do something
}  

/// Foo with 2 params only
public void DoFoo(int a, long b)
{
    /// ....
    DoFoo(a, b, "Hello");
}

public void DoFoo(int a)
{
    ///....
    DoFoo(a, 23, "Hello");
}

.....

avec les paramètres optionnels dans C # 4.0 vous mettriez en œuvre le cas d'utilisation comme le suivant,

public void DoFoo(int a = 10, long b = 23, string c = "Hello")

alors vous pouvez utiliser la méthode comme so-notez l'utilisation du paramètre nommé -

DoFoo(c:"Hello There, John Doe")

cet appel prend le paramètre a valeur 10 et le paramètre b comme 23. Une autre variante de cet appel - avis, vous n'avez pas besoin de définir les valeurs des paramètres dans l'ordre où elles apparaissent dans la méthode signature, le paramètre nommé rend la valeur explicite.

DoFoo(c:"hello again", a:100) 

un autre avantage de l'utilisation de named parameter est qu'il améliore considérablement la lisibilité et donc le maintien du code des méthodes de paramètre optionnelles.

noter comment une méthode rend pratiquement redondant avoir à définir 3 méthodes ou plus dans la méthode de surcharge. Ce que j'ai trouvé est un bon cas d'utilisation pour utiliser le paramètre optionnel en conjonction avec les paramètres nommés.

74
répondu Bikal Lem 2010-07-23 15:21:28

les paramètres optionnels fournissent des problèmes lorsque vous les exposez publiquement en tant qu'API. Un changement de nom d'un paramètre peut entraîner des problèmes. Changer la valeur par défaut conduit à des problèmes (voir par exemple ici pour quelques informations: mises en garde de C# 4.0 paramètres optionnels )

de plus, les paramètres optionnels ne peuvent être utilisés que pour les constantes de temps de compilation. Comparez ceci:

public static void Foo(IEnumerable<string> items = new List<string>()) {}
// Default parameter value for 'items' must be a compile-time constant

à ce

public static void Foo() { Foo(new List<string>());}
public static void Foo(IEnumerable<string> items) {}
//all good

mise à Jour

voici quelques lectures supplémentaires quand un constructeur avec les paramètres par défaut ne joue pas bien avec la réflexion .

53
répondu flq 2018-03-22 15:29:32

je crois qu'ils servent des buts différents. Les paramètres facultatifs sont quand vous pouvez utiliser une valeur par défaut pour un paramètre, et le code sous-jacent sera le même:

public CreditScore CheckCredit( 
  bool useHistoricalData = false,  
  bool useStrongHeuristics = true) { 
  // ... 
}
Les surcharges de la méthode

s'appliquent lorsque vous avez des paramètres (sous-ensembles de) mutuellement exclusifs. Cela signifie normalement que vous devez pré-traiter certains paramètres, ou que vous avez un code complètement différent pour les différentes "versions" de votre méthode (notez que même dans ce cas, certains paramètres peut être partagé, c'est pourquoi j'ai mentionné "sous-ensembles" ci-dessus):

public void SendSurvey(IList<Customer> customers, int surveyKey) {  
  // will loop and call the other one 
} 
public void SendSurvey(Customer customer, int surveyKey) {  
  ...  
}

(j'ai écrit à ce sujet Il ya quelque temps ici )

32
répondu Jordão 2012-06-12 09:17:55

celui-ci va presque sans dire, mais:

toutes les langues ne supportent pas les paramètres optionnels. Si vous voulez que vos bibliothèques être amical à ces langues, vous devez utiliser les surcharges.

D'accord, ce n'est même pas un problème pour la plupart des magasins. Mais vous pouvez parier que C'est pour cette raison que Microsoft n'utilise pas de paramètres optionnels dans la bibliothèque de classe de Base.

27
répondu Joe White 2010-07-23 13:08:03
Les paramètres optionnels

doivent être les derniers. Vous ne pouvez donc pas ajouter un paramètre supplémentaire à cette méthode à moins qu'elle ne soit également optionnelle. Ex:

void MyMethod(int value, int otherValue = 0);

Si vous voulez ajouter un nouveau paramètre à cette méthode sans surcharge, il doit être en option. Comme ceci

void MyMethod(int value, int otherValue = 0, int newParam = 0);

si elle ne peut pas être optionnelle, alors vous devez utiliser la surcharge et supprimer la valeur optionnelle pour 'otherValue'. Comme ceci:

void MyMethod(int value, int otherValue = 0);
void MyMethod(int value, int otherValue, int newParam);

je suppose que vous souhaitez conserver l'ordre des paramètres.

ainsi l'utilisation de paramètres optionnels réduit le nombre de méthodes que vous devez avoir dans votre classe, mais est limitée en ce qu'elles doivent être dernières.

mise à Jour Lorsque vous appelez des méthodes avec des paramètres optionnels, vous pouvez utiliser des paramètres nommés comme ceci:

void MyMethod(int value, int otherValue = 0, int newValue = 0);

MyMethod(10, newValue: 10); // Here I omitted the otherValue parameter that defaults to 0

ainsi les paramètres optionnels donnent à l'appelant plus de possibilités.

Une dernière chose. Si vous utilisez la méthode de surcharge avec une implémentation, comme ceci:

void MyMethod(int value, int otherValue)
{
   // Do the work
}

void MyMethod(int value)
{
   MyMethod(value, 0); // Do the defaulting by method overloading
}

puis en appelant 'MyMethod' comme ceci:

MyMethod(100); 

donnera 2 appels de méthode. Mais si vous utilisez des paramètres optionnels, il n'y a qu'une seule implémentation de 'MyMethod' et donc un seul appel de méthode.

9
répondu Martin Ingvar Kofoed Jensen 2010-07-23 08:42:08

n'est définitivement "mieux" que l'autre. Ils ont tous les deux leur place dans l'écriture du bon code. Les paramètres optionnels doivent être utilisés si les paramètres peuvent avoir une valeur par défaut. La surcharge de la méthode doit être utilisée lorsque la différence dans la signature va au-delà de la non définition des paramètres qui pourraient avoir des valeurs par défaut (comme que le comportement diffère en fonction des paramètres qui sont passés, et qui sont laissés à la valeur par défaut).

// this is a good candidate for optional parameters
public void DoSomething(int requiredThing, int nextThing = 12, int lastThing = 0)

// this is not, because it should be one or the other, but not both
public void DoSomething(Stream streamData = null, string stringData = null)

// these are good candidates for overloading
public void DoSomething(Stream data)
public void DoSomething(string data)

// these are no longer good candidates for overloading
public void DoSomething(int firstThing)
{
    DoSomething(firstThing, 12);
}
public void DoSomething(int firstThing, int nextThing)
{
    DoSomething(firstThing, nextThing, 0);
}
public void DoSomething(int firstThing, int nextThing, int lastThing)
{
    ...
}
7
répondu Michael Meadows 2013-08-15 11:25:06

un bon endroit pour utiliser le paramètre optionnel est WCF car il ne supporte pas la surcharge de la méthode.

4
répondu ashraf 2010-10-18 16:22:45

à propos d'une 3ème option: passer une instance d'une classe avec des propriétés correspondant à différents paramètres optionnels".

cela fournit le même avantage que les paramètres nommés et optionnels, mais je pense que c'est souvent beaucoup plus clair. Il vous donne l'occasion de grouper logiquement les paramètres si nécessaire (c.-à-d. avec la composition) et encapsuler une validation de base ainsi.

aussi, si vous attendez des clients qui consomment vos méthodes à faire toute sorte de métaprogrammation (comme la construction d'expressions linq impliquant vos méthodes), je pense que garder la signature de la méthode simple a ses avantages.

2
répondu Michael Petito 2010-07-23 16:19:42

un avantage de l'utilisation de paramètres optionnels est que vous n'avez pas besoin de faire une vérification conditionnelle dans vos méthodes comme si une chaîne était nulle ou vide si l'un des paramètres d'entrée était une chaîne. Comme il y aurait une valeur par défaut attribuée au paramètre optionnel, le codage défensif sera réduit dans une grande mesure.

les paramètres nommés donnent la flexibilité de passer des valeurs de paramètre dans n'importe quel ordre.

1
répondu Nilesh Gule 2010-07-23 11:30:15

pour répondre à votre première question,

pourquoi la plupart des classes de bibliothèques MSDN utilisent surcharge au lieu d'optionnel les paramètres?

il est pour la compatibilité arrière.

lorsque vous ouvrez un projet C# 2, 3.0 ou 3.5 dans VS2010, il est automatiquement mis à jour.

imaginez les inconvénients que cela créerait si chacune des surcharges utilisées dans le projet devait être convertie pour correspondre à la déclaration de paramètre optionnelle correspondante.

D'ailleurs, comme dit le dicton, "pourquoi réparer ce qui n'est pas cassé?". Il n'est pas nécessaire de remplacer les surcharges qui fonctionnent déjà par de nouvelles implémentations.

0
répondu Alex Essilfie 2010-07-23 15:55:37