Depuis C # 7.2 + , vous pouvez ajouter un modificateur de paramètre in
avant le type de paramètre pour définir un paramètre comme const, essentiellement.
C'est comme les mots clés ref ou out, sauf que les arguments in ne peuvent pas être modifiés par la méthode appelée. - MSDN
Exemple de MSDN:
void InArgExample(in int number)
{
number = 19; // error CS8331, it prevents modification of this parameter
}
Pourquoi est-ce utile? Vous pouvez garantir à l'appelant que l'argument passé ne sera pas modifié suite à l'appel de cette fonction. Une promesse en d'autres termes.
Selon SOLID principes de conception et Clean Code de Robert Martin, est-ce considéré comme une odeur de code dans le même sens que les paramètres out
?
Sources:
Vous avez pris la ligne de MSDN hors contexte.
La partie la plus importante de la page est la première phrase: "Le mot clé in
fait passer les arguments par référence." Il est principalement à cet égard que le mot-clé est similaire à out
et ref
.
Ceci est important lorsque vous passez de grandes struct
s aux fonctions. Les passer sans mot-clé est inefficace car la structure est copiée. (Aucune modification ne doit être visible à l'extérieur.) Le passage par référence est plus efficace.
Cependant, l'utilisation des anciens mots clés out
et ref
à cet effet est problématique. out
est complètement inutile: il ne peut pas être utilisé pour transmettre des informations à la fonction. ref
est possible, mais déroutant: il permet à la fonction de modifier son paramètre (avec des changements visibles à l'extérieur). C'est inhabituel pour les structures. C'est une source probable de bugs si vous le faites. Et c'est communiquer la mauvaise intention si vous n'avez pas l'intention de le faire.
D'où le mot-clé in
: un moyen de passer des structures par référence sans en permettre la modification. Et donc la phrase que vous avez citée.
Utiliser in
pour empêcher la modification du paramètre uniquement (comme dans l'exemple MSDN) au lieu de l'utiliser pour améliorer l'efficacité is une odeur de code, soit dit en passant. Ne passez jamais int
s comme in
. Il n'y a aucun intérêt à empêcher les modifications des paramètres normaux par valeur, car les modifications ne peuvent de toute façon pas être vues en dehors de la fonction. (Cela confond certains nouveaux programmeurs, mais la compréhension par valeur et par référence est quelque chose qu'ils doivent apprendre de toute façon.)
Non, l'utilisation du mot clé in
pour faire passer un argument par référence à une méthode en lecture seule n'est pas une odeur de code.
La modification d'un paramètre d'entrée est un effet secondaire. Cela peut facilement conduire à un code difficile à raisonner et à modifier.
Le principe de séparation des requêtes (CQS) de Bertrand Meyer stipule qu'une méthode doit être soit une commande soit une requête. Si une méthode est une commande, elle mute l'état (de ses variables d'instance), mais ne renvoie rien (void). Si une méthode est une requête, elle a une valeur de retour, mais ne change pas d'état.
Si vous suivez ce principe, votre code devient généralement plus facile à raisonner et contient moins de bogues. Par exemple, toute méthode qui renvoie une valeur peut être appelée plusieurs fois en toute sécurité et elle produira toujours le même résultat.
Retour au mot clé in
. MSDN écrit:
La transmission de ces arguments par référence évite la copie (potentiellement) coûteuse
En utilisant le mot clé in, vous signalez à l'appelant que l'argument sera transmis à la méthode comme référence, mais il est sûr de le faire, car il ne sera pas modifié.
En tant que sidenote, je conseillerais que lorsque vous utilisez in
dans la signature de méthode, spécifiez-le également dans l'appelant. Il montre l'intention et quand il y a une surcharge sans in
, cette méthode sera choisie en premier.
Bien que les mots "in" et "out" soient liés, je pense qu'ils sont très différents dans ce cas. Alors que le mot clé out
fournit un autre moyen de renvoyer la sortie, le paramètre in
ressemble plus à un moyen d'ajouter "lecture seule" au paramètre d'entrée. Que cela soit important ou non pour l'appelant, je ne peux pas vraiment décider. Je pense que cela devrait être clair de toute façon.