web-dev-qa-db-fra.com

Meilleure pratique pour ajouter un paramètre supplémentaire à une fonction

Je travaille actuellement avec un très grand système et j'ai été invité à ajouter un paramètre supplémentaire à une méthode appelée à plus de 200 endroits différents.

La signature de la méthode ressemble à ceci:

public static bool SendMessageAndLog(long id, long userId, string message, string cc="", params Attachment[] attachments) 
{ ... }

J'ai besoin de pouvoir enregistrer l'ID de l'événement que ce message est associé. Je suis un peu coincé entre 2 solutions:

  1. Création d'une nouvelle méthode qui fait exactement la même chose, mais prend également l'identifiant d'événement, en train de décaper l'ancienne méthode et de la faire appeler la nouvelle méthode
  2. Ajout d'un paramètre facultatif pour l'ID d'événement et passer et utiliser des paramètres nommés pour les 200 appels qui ressemblent à une douleur massive

Y a-t-il plus d'autres solutions potentielles à cela? Quelle serait la meilleure pratique dans cette affaire en gardant à l'esprit que je ne peux pas trop refroidir cela trop.

5
GoodPie

Créez une nouvelle méthode avec le paramètre supplémentaire et déplacez tout le code à partir de la méthode d'origine, ce qui lui permet d'utiliser le paramètre supplémentaire comme vous êtes censé. Laissez la méthode d'origine (sans paramètre supplémentaire) qui appellerait simplement la nouvelle méthode avec une valeur par défaut du paramètre supplémentaire, en faisant essentiellement une méthode d'emballage. Ceci, bien sûr, ne fonctionne que s'il existe une valeur par défaut du paramètre supplémentaire. S'il n'y en a pas, mais la valeur diffère de l'appel à appeler, alors vous devez mordre la balle et simplement refroidir tout ce qui ne devrait pas être trop difficile, car une fois que vous cassez la signature en ajoutant le paramètre supplémentaire, le compilateur sera vous dire où vous devez le réparer d'autre.

Dans votre cas particulier, si vous avez le mappage d'identifiant d'événement de message qui ne change pas pour la durée de l'exécution du programme, vous pouvez simplement créer la carte en tant qu'attribut interne de la classe contenant la méthode, Et la première ligne de votre méthode serait de lire la carte et d'obtenir l'identifiant de l'événement en fonction du message. Vous l'utilisez ensuite comme vous le souhaitez. De cette façon, vous n'avez pas besoin de changer la signature de la méthode. Il ne devrait même pas y avoir une telle performance, car je ne m'attends pas à ce que la carte ait trop d'éléments.

24
Vladimir Stokic

Bien que je suis d'accord avec la réponse acceptée, il existe également deux autres approches que vous pourriez adopter en fonction des exigences.

1. Surcharge de la méthode

Vous pouvez avoir plusieurs méthodes dans une classe C # qui ont le même nom et effectuer la même action, mais prendre différents paramètres. Bien que c'était certes la meilleure approche pour votre propre scénario en raison de la duplication du code. La méthode que les incendies dépendront des paramètres que vous fournissez.

public static bool SendMessageAndLog(long id, long userId, string message, string cc="", 
                                     params Attachment[] attachments) 
{ ... }

// overloaded method
public static bool SendMessageAndLog(long id, long userId, string message,  string cc="", 
                                     int eventId, params Attachment[] attachments) 
{ ... }

2. Paramètres nullables/Attribuer une valeur de paramètre par défaut

Cette approche vous permet de conserver la méthode unique, mais tous les paramètres que vous affectez une valeur par défaut à devoir être les paramètres de la plupart dans la méthode. Cela signifie que si vous devez ajouter un paramètre supplémentaire plus tard et ne peut pas ré-écrire le code appelant la méthode, le nouveau paramètre doit également avoir une valeur par défaut attribuée (qui peut être null si vous le souhaitez.).

Vous auriez également besoin de supprimer params des paramètres de votre étui de nouveau non idéal! Bien que je ne sois pas un fan de params Lorsque vous pouvez simplement transmettre une liste nommée ou une matrice à sa place.

public static bool SendMessageAndLog(long id, long userId, string message, string cc="", 
                                     Attachment[] attachments, int? eventId = null) 
{ ... }

//You can now call this method in two ways...

//1)eventId param not provided so it will default to null inside method block
SendMessageAndLog(id, userId, message, attachments);

//2)eventId value provided so it will be whatever value you provide.
SendMessageAndLog(id, userid, message, attachments, eventId);   
3
Sean T