Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 227625
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 11, 20262026-05-11T19:36:51+00:00 2026-05-11T19:36:51+00:00

I frequently read that struct s should be immutable – aren’t they by definition?

  • 0

I frequently read that structs should be immutable – aren’t they by definition?

Do you consider int to be immutable?

int i = 0;
i = i + 123;

Seems okay – we get a new int and assign it back to i. What about this?

i++;

Okay, we can think of it as a shortcut.

i = i + 1;

What about the struct Point?

Point p = new Point(1, 2);
p.Offset(3, 4);

Does this really mutate the point (1, 2)? Shouldn’t we think of it as a shortcut for the following with Point.Offset() returning a new point?

p = p.Offset(3, 4);

The background of this thought is this – how can a value type with no identity be mutable? You have to look at it at least twice to determine if it changed. But how can you do this without an identity?

I don’t want to complicate reasoning about this by considering ref parameters and boxing. I am also aware that p = p.Offset(3, 4); expresses immutability much better than p.Offset(3, 4); does. But the question remains – aren’t value types immutable by definition?

UPDATE

I think there are at least two concepts involved – the mutability of a variable or field and the mutability of the value of a variable.

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).
    }
}

In the example we have to fields – a mutable one and a immutable one. Because a value type field contains the whole value, a value type stored in a immutable field must be immutable, too. I am still quite suprised by the result – I did not exspect the readonly field to remain unmodified.

Variables (besides constants) are allways mutable, hence they imply no restriction on the mutability of value types.


The answer seems not to be that straight forward so I will rephrase the question.

Given the following.

public struct Foo
{
    public void DoStuff(whatEverArgumentsYouLike)
    {
        // Do what ever you like to do.
    }

    // Put in everything you like - fields, constants, methods, properties ...
}

Can you give a completed version of Foo and an usage example – that may include ref parameters and boxing – so that it is not possible to rewrite all occurences of

foo.DoStuff(whatEverArgumentsYouLike);

with

foo = foo.DoStuff(whatEverArgumentsYouLike);
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-11T19:36:51+00:00Added an answer on May 11, 2026 at 7:36 pm

    An object is immutable if its state
    doesn’t change once the object has
    been created.

    Short answer: No, value types are not immutable by definition. Both structs and classes can be either mutable or immutable. All four combinations are possible. If a struct or class has non-readonly public fields, public properties with setters, or methods which set private fields, it is mutable because you can change its state without creating a new instance of that type.


    Long answer: First of all, the question of immutability only applies to structs or classes with fields or properties. The most basic types (numbers, strings, and null) are inherently immutable because there is nothing (field/property) to change about them. A 5 is a 5 is a 5. Any operation on the 5 only returns another immutable value.

    You can create mutable structs such as System.Drawing.Point. Both X and Y have setters which modify the struct’s fields:

    Point p = new Point(0, 0);
    p.X = 5;
    // we modify the struct through property setter X
    // still the same Point instance, but its state has changed
    // it's property X is now 5
    

    Some people seem to confuse immutablity with the fact that value types are passed by value (hence their name) and not by reference.

    void Main()
    {
        Point p1 = new Point(0, 0);
        SetX(p1, 5);
        Console.WriteLine(p1.ToString());
    }
    
    void SetX(Point p2, int value)
    {
        p2.X = value;
    }
    

    In this case Console.WriteLine() writes "{X=0,Y=0}". Here p1 was not modified because SetX() modified p2 which is a copy of p1. This happens because p1 is a value type, not because it is immutable (it isn’t).

    Why should value types be immutable? Lots of reasons… See this question. Mostly it’s because mutable value types lead to all sorts of not-so-obvious bugs. In the above example the programmer might have expected p1 to be (5, 0) after calling SetX(). Or imagine sorting by a value which can later change. Then your sorted collection will no longer be sorted as expected. The same goes for dictionaries and hashes. The Fabulous Eric Lippert (blog) has written a whole series about immutability and why he believes it’s the future of C#. Here’s one of his examples that lets you "modify" a read-only variable.


    UPDATE: your example with:

    this.readOnlyPoint.Offset(3, 4); // Is still (1, 2).
    

    is exactly the what Lippert referred to in his post about modifying read-only variables. Offset(3,4) actually modified a Point, but it was a copy of readOnlyPoint, and it was never assigned to anything, so it’s lost.

    And that is why mutable value types are evil: They let you think you are modifying something, when sometimes you are actually modifying a copy, which leads to unexpected bugs. If Point was immutable, Offset() would have to return a new Point, and you would not have been able to assign it to readOnlyPoint. And then you go "Oh right, it’s read-only for a reason. Why was I trying to change it? Good thing the compiler stopped me now."


    UPDATE: About your rephrased request… I think I know what you’re getting at. In a way, you can "think" of structs as being internally immutable, that modifying a struct is that same as replacing it with a modified copy. It might even be what the CLR does internally in memory, for all I know. (That’s how flash memory works. You cannot edit just a few bytes, you need to read a whole block of kilobytes into memory, modify the few you want, and write the whole block back.) However, even if they were "internally immutable", that is an implementation detail and for us developers as users of structs (their interface or API, if you will), they can be changed. We can’t ignore that fact and "think of them as immutable".

    In a comment you said "you cannot have a reference to the value of field or variable". You are assuming that every struct variable has a different copy, such that modifying one copy does not affect the others. That is not entirely true. The lines marked below are not replaceable if…

    interface IFoo { DoStuff(); }
    struct Foo : IFoo { /* ... */ }
    
    IFoo otherFoo = new Foo();
    IFoo foo = otherFoo;
    foo.DoStuff(whatEverArgumentsYouLike); // line #1
    foo = foo.DoStuff(whatEverArgumentsYouLike); // line #2
    

    Lines #1 and #2 do not have the same results… Why? Because foo and otherFoo refer to the same boxed instance of Foo. Whatever is changed in foo in line #1 reflects in otherFoo. Line #2 replaces foo with a new value and does nothing to otherFoo (assuming that DoStuff() returns a new IFoo instance and does not modify foo itself).

    Foo foo1 = new Foo(); // creates first instance
    Foo foo2 = foo1; // create a copy (2nd instance)
    IFoo foo3 = foo2; // no copy here! foo2 and foo3 refer to same instance
    

    Modifying foo1 won’t affect foo2 or foo3. Modifying foo2 will reflect in foo3, but not in foo1. Modifying foo3 will reflect in foo2 but not in foo1.

    Confusing? Stick to immutable value types and you eliminate the urge of modifying any of them.


    UPDATE: fixed typo in first code sample

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Ask A Question

Stats

  • Questions 117k
  • Answers 118k
  • Best Answers 0
  • User 1
  • Popular
  • Answers
  • Editorial Team

    How to approach applying for a job at a company ...

    • 7 Answers
  • Editorial Team

    How to handle personal stress caused by utterly incompetent and ...

    • 5 Answers
  • Editorial Team

    What is a programmer’s life like?

    • 5 Answers
  • Editorial Team
    Editorial Team added an answer class Program { static void Main(string[] args) { Timer timer… May 11, 2026 at 10:50 pm
  • Editorial Team
    Editorial Team added an answer Use GROUP_CONCAT SELECT GROUP_CONCAT(bar) FROM TABLE GROUP BY foo; May 11, 2026 at 10:50 pm
  • Editorial Team
    Editorial Team added an answer Your code doesn't work because the function is not returning… May 11, 2026 at 10:50 pm

Related Questions

I frequently read that struct s should be immutable - aren't they by definition?
I'm at a point in my development learning where I feel like I must
I frequently hear/read the following advice: Always make a copy of an event before
I've frequently seen a space preceding the closing slash in XML and HTML tags.
Often, programmers write code that generates other code. (The technical term is metaprogramming ,

Trending Tags

analytics british company computer developers django employee employer english facebook french google interview javascript language life php programmer programs salary

Top Members

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.