s tipos de valor são imutáveis por definiçã
Eu frequentemente leio questruct
s deve ser imutável - não são por definição?
Você consideraint
ser imutável?
int i = 0;
i = i + 123;
Parece bom - recebemos um novoint
e atribua-o de volta ai
. Que tal isso?
i++;
Ok, podemos pensar nisso como um atalh
i = i + 1;
Que tal ostruct
Point
?
Point p = new Point(1, 2);
p.Offset(3, 4);
Isso realmente muda o ponto(1, 2)
? Não devemos pensar nisso como um atalho para o seguinte comPoint.Offset()
retornando um novo ponto?
p = p.Offset(3, 4);
O pano de fundo desse pensamento é este: como um tipo de valor sem identidade pode ser mutável? Você precisa examiná-lo pelo menos duas vezes para determinar se ele foi alterado. Mas como você pode fazer isso sem uma identidade?
Não quero complicar o raciocínio sobre isso, considerandoref
parâmetros e boxe. Também estou ciente de quep = p.Offset(3, 4);
expressa imutabilidade muito melhor do quep.Offset(3, 4);
faz. Mas a questão permanece: os tipos de valor não são imutáveis por definição?
ATUALIZA
cho que há pelo menos dois conceitos envolvidos: a mutabilidade de uma variável ou campo e a mutabilidade do valor de uma variáve
public class Foo
{
private Point point;
private readonly Point readOnlyPoint;
public Foo()
{
this.point = new Point(1, 2);
this.readOnlyPoint = new Point(1, 2);
}
public void Bar()
{
this.point = new Point(1, 2);
this.readOnlyPoint = new Point(1, 2); // Does not compile.
this.point.Offset(3, 4); // Is now (4, 6).
this.readOnlyPoint.Offset(3, 4); // Is still (1, 2).
}
}
No exemplo, temos que campos - um mutável e um imutável. Como um campo de tipo de valor contém o valor inteiro, um tipo de valor armazenado em um campo imutável também deve ser imutável. Ainda estou bastante surpreso com o resultado - não esperava que o campo somente leitura permanecesse inalterad
s variáveis (além das constantes) são sempre mutáveis, portanto, elas não implicam restrições à mutabilidade dos tipos de valo
A resposta não parece ser tão direta, então vou reformular a pergunt
Dado o seguinte.
public struct Foo
{
public void DoStuff(whatEverArgumentsYouLike)
{
// Do what ever you like to do.
}
// Put in everything you like - fields, constants, methods, properties ...
}
Pode fornecer uma versão completa doFoo
e um exemplo de uso - que pode incluirref
parâmetros e boxe - para que não seja possível reescrever todas as ocorrências de
foo.DoStuff(whatEverArgumentsYouLike);
co
foo = foo.DoStuff(whatEverArgumentsYouLike);