in .NET 4 BETA 2, il y a le nouvel espace de noms numériques avec Mais je suis un peu confus par l'opérateur post-incraction ( C'est ce que MSDN dit à propos de l'opérateur d'incrément: P> Parce que les objets BigInteger sont
immuable, l'opérateur d'incrément
crée un nouvel objet BigInteger dont
la valeur est une plus que la biginteger
objet représenté par la valeur.
Par conséquent, des appels répétés à l'incrément
peut être cher. p>
blockQuote> Bien et bien, j'aurais compris si je devais utiliser Toutes les pensées? p> p> struct biginteger code>. Documentation stipule que C'est un type immuable, comme je l'aurais attendu.
++ code>). Cela semble non-muté de la valeur. Les travaux suivants tandis que la boucle fonctionne: p>
b = b ++ code> mais apparemment
++ code> est suffisant pour changer une valeur . P>
5 Réponses :
Les opérateurs est équivalent à: p> maintenant, comme commenté, cela peut sembler comme ça casse une immuabilité, mais elle fait pas. p> Vous devez plutôt regarder ce code comme le faisant: p> Ceci laissera deux objets en mémoire, la valeur de BigInteger d'origine et la Nouveau, maintenant référencé par b. Vous pouvez facilement vérifier que c'est ce qui se passe avec le code suivant: p> de sorte que l'objet d'origine n'a pas changé, il ne casse donc pas l'immuabilité et de répondre à la nouvelle partie. de la question, cela devrait être du thread-coffre-fort. P> C'est la même chose qui arrive à des chaînes: p> ++ code> et
- code> sont implémentés en termes de normal
+ code> et
- code> opérateurs, donc en réalité:
Cela semble raisonnable, mais il semble toujours casser l'immuabilité. Je vais éditer la question un peu.
Dans S + = S2 Code> Il existe une affectation visible. Il convient si vous acceptez que
B ++ code> est également une affectation, c'est-à-dire
b = b + 1 code>. Mais
++ code> reste toujours / ressemble à la mutation.
Étant donné que BigInteger est immuable, B ++ sera juste équivalent à: Après cette opération, la température est recyclée par le GC et la mémoire est libérée. P> P>
OK, sauf pour la partie GC. C'est une structure (avec un tableau interne).
Oui, et la seule différence est que la structure est stockée sur la pile alors que cette classe est stockée dans le tas.
Ted, où pensez-vous qu'un champ de biginteger dans un objet est stocké?
C'est dans le tas, avec une référence à elle stockée sur la pile.
OK, mais qu'en est-il de l'opérateur de négation unaire défini sur BigInteger: Il semble casser le motif d'immutabilité et muter directement l'objet BigInteger. Donc p> modifie réellement une biginteger existante en place sans retourner un nouvel objet. P> P>
BigInteger b = BigInteger.One; b++; // immutable ? In your example b is a variable, which is just a slot of memory in the current method's stack frame. It is initialised to One, and b++ takes b, creates a new BigInteger (with the incremented value) and returns it. variable b now has the state from the returned new BigInteger.To be honest immutability as a concept is much clearer when dealing with reference types, because there is an object on the heap whose internal state never changes, so when an operation/method returns a new object with different state it's kind of obvious (e.g. you can do an object reference equality check with object.ReferenceEquals(object, object).For value types there is no object on the heap, there is just the slot in memory that contains the bits that are the value.
de la Microsoft Docs, juste après avoir parlé de ++:
Bien que cet exemple semble modifier la valeur de l'objet existant, ce n'est pas le cas.
Les objets BigInteger sont immuables, ce qui signifie qu'intier, le jeu de langue commune crée en fait un nouvel objet BigInteger et l'attribue une valeur supérieure à celle de sa valeur précédente. Ce nouvel objet est ensuite retourné à l'appelant. P>
Non, BigInteger est une structure (type de valeur) et il n'y a pas de pointeur (référence) ici.
@HENKHOLTERMAN Eh bien, le pointeur est soit en B, soit dans une structure que B pointe de chaque sens, un peu de pointe doit changer.
@HENKHOLTERMAN OK, je vais vous donner un exemple, disons que vous avez une chaîne, qui est un type de valeur et que vous le transmettez à une fonction, si vous regardez dans le désastage, vous verrez qu'une seule valeur de 64/32 bits est transmis comme un paramètre à la fonction, car notre chaîne a probablement plus de 64 bits, nous pouvons supposer que nous ne passions pas la chaîne, nous passons un pointeur, un pointeur sur une copie de la chaîne, mais toujours, un aiguille.
Une chaîne est un type de référence. BigInteger n'est pas. Il existe de meilleures références que le code IL.
@Henkholeshterman mon mauvais, mais j'en ai un meilleur exemple, si vous passez une grande structure à une fonction, vous passez un pointeur sur la structure même si une structure est un type de valeur.
Êtes-vous confondre cela avec C ou C ++?
Il semble que je suis, je modifierai ma réponse pour être correct, désolé
Et maintenant comparez-le à la meilleure réponse ici.