Tout d'abord, Jon, Michael et Jared réponses sont essentiellement correct mais j'ai un peu plus de choses que je voudrais ajouter.
Qu'entend-on par "impurs" méthode?
Il est plus facile de caractériser pur méthodes. Un "pur" méthode possède les caractéristiques suivantes:
- Sa sortie est entièrement déterminée par son entrée, sa sortie ne dépend pas d'externalités comme le moment de la journée ou les bits sur votre disque dur. Sa sortie ne dépend pas de son histoire; à l'appel de la méthode, avec un argument donné deux fois devraient donner le même résultat.
- Une pure méthode ne produit pas de mutations observables dans le monde autour d'elle. Une pure méthode peut choisir de muter privé de l'état pour des raisons d'efficacité, mais une pure méthode n'est pas, disons, de muter un champ de son argument.
Par exemple, Math.Cos
est une méthode pure. Sa sortie ne dépend que de son entrée, et l'entrée n'est pas modifiée par l'appel.
Un impur est une méthode qui n'est pas pur.
Quels sont les dangers du passage readonly les structures de l'impur méthodes?
Il y a deux qui me viennent à l'esprit. Le premier est celui que l'a souligné Jon, Michael et Jared, et c'est celui que Resharper est pour vous avertir au sujet. Lorsque vous appelez une méthode sur un struct, on passe toujours une référence à la variable qui est le récepteur, dans le cas de la méthode tient à la mutation de l'variable.
Alors que faire si vous appelez cette méthode sur une valeur, plutôt qu'une variable? Dans ce cas, nous faisons une variable temporaire, copie de la valeur, et de passer une référence à la variable.
Une lecture seule variable est considérée comme une valeur, car il ne peut pas être muté à l'extérieur du constructeur. Nous sommes donc la copie de la variable à une autre variable, et de l'impur méthode est peut-être la mutation de la copie, lorsque vous avez l'intention à muter la variable.
C'est le danger de passage d'un readonly struct comme un récepteur. Il y a également un risque de passage d'une structure qui contient un champ en lecture seule. Une structure qui contient un champ en lecture seule est une pratique courante, mais c'est surtout l'écriture d'un chèque que le type de système de ne pas avoir les fonds à la trésorerie; le "read-only-ness" d'une variable donnée est déterminé par le propriétaire de l'espace de stockage. Une instance d'un type de référence "propriétaire" de son propre espace de stockage, mais une instance d'un type de valeur ne fait pas!
struct S
{
private readonly int x;
public S(int x) { this.x = x; }
public void Badness(ref S s)
{
Console.WriteLine(this.x);
s = new S(this.x + 1);
// This should be the same, right?
Console.WriteLine(this.x);
}
}
On pense que l' this.x
ne va pas changer parce que x est un champ en lecture seule et Badness
n'est pas un constructeur. Mais...
S s = new S(1);
s.Badness(ref s);
... montre clairement la fausseté de cette. this
et s
reportez-vous à la même variable, et que la variable n'est pas en lecture seule!