s tipos de valor são imutáveis por definiçã

Eu frequentemente leio questructs 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);