Readonly vs static readonly clarification

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty height:90px;width:728px;box-sizing:border-box;








6















I've run into an interesting situation I am trying to understand. I have a readonly struct field in my class. This means that when I reference it, it references a copy and not the actual one, so when I call a change method, it will be working with a copy, and the original will remain unchanged.



That is not what I am observing. I only see the expected behavior with a static field. I expected the behavior for both types.



private struct junk

public int i;

public void change()

i += 1;



private readonly junk jk;
private static readonly junk jk2;

public Form1()

InitializeComponent();
jk.change();
//jk.i is now 1, why? Shouldn't it be changing a copy and not the original jk?
jk2.change();
//jk2.i is 0










share|improve this question

















  • 6





    Mutable value types - just say no.

    – Damien_The_Unbeliever
    Mar 10 at 17:34







  • 3





    please get rid of the irrelevant call to InitializeComponent() and insert code that prints the values of jk.i and jk2.i and show us what it prints. We do not care to read what you think the values are, we want to see what the values are.

    – Mike Nakis
    Mar 10 at 17:34






  • 2





    (And we also want to see what makes you think the values are what you claim they are.)

    – Mike Nakis
    Mar 10 at 17:35






  • 2





    A warning would have been nice, but the C# compiler does not have the plumbing that can ensure that change() has an observable side-effect. A counter-example is the C++/CLI compiler, it always assumes and that doesn't make programmers happy either. Add static Form1() to see that it is allowed to mutate the jk2 value.

    – Hans Passant
    Mar 10 at 18:22

















6















I've run into an interesting situation I am trying to understand. I have a readonly struct field in my class. This means that when I reference it, it references a copy and not the actual one, so when I call a change method, it will be working with a copy, and the original will remain unchanged.



That is not what I am observing. I only see the expected behavior with a static field. I expected the behavior for both types.



private struct junk

public int i;

public void change()

i += 1;



private readonly junk jk;
private static readonly junk jk2;

public Form1()

InitializeComponent();
jk.change();
//jk.i is now 1, why? Shouldn't it be changing a copy and not the original jk?
jk2.change();
//jk2.i is 0










share|improve this question

















  • 6





    Mutable value types - just say no.

    – Damien_The_Unbeliever
    Mar 10 at 17:34







  • 3





    please get rid of the irrelevant call to InitializeComponent() and insert code that prints the values of jk.i and jk2.i and show us what it prints. We do not care to read what you think the values are, we want to see what the values are.

    – Mike Nakis
    Mar 10 at 17:34






  • 2





    (And we also want to see what makes you think the values are what you claim they are.)

    – Mike Nakis
    Mar 10 at 17:35






  • 2





    A warning would have been nice, but the C# compiler does not have the plumbing that can ensure that change() has an observable side-effect. A counter-example is the C++/CLI compiler, it always assumes and that doesn't make programmers happy either. Add static Form1() to see that it is allowed to mutate the jk2 value.

    – Hans Passant
    Mar 10 at 18:22













6












6








6


1






I've run into an interesting situation I am trying to understand. I have a readonly struct field in my class. This means that when I reference it, it references a copy and not the actual one, so when I call a change method, it will be working with a copy, and the original will remain unchanged.



That is not what I am observing. I only see the expected behavior with a static field. I expected the behavior for both types.



private struct junk

public int i;

public void change()

i += 1;



private readonly junk jk;
private static readonly junk jk2;

public Form1()

InitializeComponent();
jk.change();
//jk.i is now 1, why? Shouldn't it be changing a copy and not the original jk?
jk2.change();
//jk2.i is 0










share|improve this question














I've run into an interesting situation I am trying to understand. I have a readonly struct field in my class. This means that when I reference it, it references a copy and not the actual one, so when I call a change method, it will be working with a copy, and the original will remain unchanged.



That is not what I am observing. I only see the expected behavior with a static field. I expected the behavior for both types.



private struct junk

public int i;

public void change()

i += 1;



private readonly junk jk;
private static readonly junk jk2;

public Form1()

InitializeComponent();
jk.change();
//jk.i is now 1, why? Shouldn't it be changing a copy and not the original jk?
jk2.change();
//jk2.i is 0







c#






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Mar 10 at 17:29









Endel_Endel_

341




341







  • 6





    Mutable value types - just say no.

    – Damien_The_Unbeliever
    Mar 10 at 17:34







  • 3





    please get rid of the irrelevant call to InitializeComponent() and insert code that prints the values of jk.i and jk2.i and show us what it prints. We do not care to read what you think the values are, we want to see what the values are.

    – Mike Nakis
    Mar 10 at 17:34






  • 2





    (And we also want to see what makes you think the values are what you claim they are.)

    – Mike Nakis
    Mar 10 at 17:35






  • 2





    A warning would have been nice, but the C# compiler does not have the plumbing that can ensure that change() has an observable side-effect. A counter-example is the C++/CLI compiler, it always assumes and that doesn't make programmers happy either. Add static Form1() to see that it is allowed to mutate the jk2 value.

    – Hans Passant
    Mar 10 at 18:22












  • 6





    Mutable value types - just say no.

    – Damien_The_Unbeliever
    Mar 10 at 17:34







  • 3





    please get rid of the irrelevant call to InitializeComponent() and insert code that prints the values of jk.i and jk2.i and show us what it prints. We do not care to read what you think the values are, we want to see what the values are.

    – Mike Nakis
    Mar 10 at 17:34






  • 2





    (And we also want to see what makes you think the values are what you claim they are.)

    – Mike Nakis
    Mar 10 at 17:35






  • 2





    A warning would have been nice, but the C# compiler does not have the plumbing that can ensure that change() has an observable side-effect. A counter-example is the C++/CLI compiler, it always assumes and that doesn't make programmers happy either. Add static Form1() to see that it is allowed to mutate the jk2 value.

    – Hans Passant
    Mar 10 at 18:22







6




6





Mutable value types - just say no.

– Damien_The_Unbeliever
Mar 10 at 17:34






Mutable value types - just say no.

– Damien_The_Unbeliever
Mar 10 at 17:34





3




3





please get rid of the irrelevant call to InitializeComponent() and insert code that prints the values of jk.i and jk2.i and show us what it prints. We do not care to read what you think the values are, we want to see what the values are.

– Mike Nakis
Mar 10 at 17:34





please get rid of the irrelevant call to InitializeComponent() and insert code that prints the values of jk.i and jk2.i and show us what it prints. We do not care to read what you think the values are, we want to see what the values are.

– Mike Nakis
Mar 10 at 17:34




2




2





(And we also want to see what makes you think the values are what you claim they are.)

– Mike Nakis
Mar 10 at 17:35





(And we also want to see what makes you think the values are what you claim they are.)

– Mike Nakis
Mar 10 at 17:35




2




2





A warning would have been nice, but the C# compiler does not have the plumbing that can ensure that change() has an observable side-effect. A counter-example is the C++/CLI compiler, it always assumes and that doesn't make programmers happy either. Add static Form1() to see that it is allowed to mutate the jk2 value.

– Hans Passant
Mar 10 at 18:22





A warning would have been nice, but the C# compiler does not have the plumbing that can ensure that change() has an observable side-effect. A counter-example is the C++/CLI compiler, it always assumes and that doesn't make programmers happy either. Add static Form1() to see that it is allowed to mutate the jk2 value.

– Hans Passant
Mar 10 at 18:22












1 Answer
1






active

oldest

votes


















6















I have a readonly struct field in my class. This means that when I reference it, it references a copy and not the actual one, so when I call a change method, it will be working with a copy, and the original will remain unchanged.




That's not at all what the readonly modifier does. The readonly modifier prevents you from assigning a new value to jk anywhere but in a constructor. Then, the static modifier allows you to reuse that value independently of the instance of Form1 you are working with.

That said, neither readonly nor static is making the weird behavior you are describing because that exact behavior cannot be reproduced with the code you've posted.



Look at a simpler example in a Console application (which you can try here):



public class Program

private readonly junk jk;
private static readonly junk jk2;

public static void Main()

var program = new Program();
program.jk.change();
Console.WriteLine(program.jk.i); // prints 0

jk2.change();
Console.WriteLine(jk2.i); // prints 0



public struct junk

public int i;
public void change()

i += 1;




Then, as @Damien_The_Unbeliever commented, try to avoid mutable structs as much as you can.






share|improve this answer























    Your Answer






    StackExchange.ifUsing("editor", function ()
    StackExchange.using("externalEditor", function ()
    StackExchange.using("snippets", function ()
    StackExchange.snippets.init();
    );
    );
    , "code-snippets");

    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "1"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader:
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    ,
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );













    draft saved

    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55090417%2freadonly-vs-static-readonly-clarification%23new-answer', 'question_page');

    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    6















    I have a readonly struct field in my class. This means that when I reference it, it references a copy and not the actual one, so when I call a change method, it will be working with a copy, and the original will remain unchanged.




    That's not at all what the readonly modifier does. The readonly modifier prevents you from assigning a new value to jk anywhere but in a constructor. Then, the static modifier allows you to reuse that value independently of the instance of Form1 you are working with.

    That said, neither readonly nor static is making the weird behavior you are describing because that exact behavior cannot be reproduced with the code you've posted.



    Look at a simpler example in a Console application (which you can try here):



    public class Program

    private readonly junk jk;
    private static readonly junk jk2;

    public static void Main()

    var program = new Program();
    program.jk.change();
    Console.WriteLine(program.jk.i); // prints 0

    jk2.change();
    Console.WriteLine(jk2.i); // prints 0



    public struct junk

    public int i;
    public void change()

    i += 1;




    Then, as @Damien_The_Unbeliever commented, try to avoid mutable structs as much as you can.






    share|improve this answer



























      6















      I have a readonly struct field in my class. This means that when I reference it, it references a copy and not the actual one, so when I call a change method, it will be working with a copy, and the original will remain unchanged.




      That's not at all what the readonly modifier does. The readonly modifier prevents you from assigning a new value to jk anywhere but in a constructor. Then, the static modifier allows you to reuse that value independently of the instance of Form1 you are working with.

      That said, neither readonly nor static is making the weird behavior you are describing because that exact behavior cannot be reproduced with the code you've posted.



      Look at a simpler example in a Console application (which you can try here):



      public class Program

      private readonly junk jk;
      private static readonly junk jk2;

      public static void Main()

      var program = new Program();
      program.jk.change();
      Console.WriteLine(program.jk.i); // prints 0

      jk2.change();
      Console.WriteLine(jk2.i); // prints 0



      public struct junk

      public int i;
      public void change()

      i += 1;




      Then, as @Damien_The_Unbeliever commented, try to avoid mutable structs as much as you can.






      share|improve this answer

























        6












        6








        6








        I have a readonly struct field in my class. This means that when I reference it, it references a copy and not the actual one, so when I call a change method, it will be working with a copy, and the original will remain unchanged.




        That's not at all what the readonly modifier does. The readonly modifier prevents you from assigning a new value to jk anywhere but in a constructor. Then, the static modifier allows you to reuse that value independently of the instance of Form1 you are working with.

        That said, neither readonly nor static is making the weird behavior you are describing because that exact behavior cannot be reproduced with the code you've posted.



        Look at a simpler example in a Console application (which you can try here):



        public class Program

        private readonly junk jk;
        private static readonly junk jk2;

        public static void Main()

        var program = new Program();
        program.jk.change();
        Console.WriteLine(program.jk.i); // prints 0

        jk2.change();
        Console.WriteLine(jk2.i); // prints 0



        public struct junk

        public int i;
        public void change()

        i += 1;




        Then, as @Damien_The_Unbeliever commented, try to avoid mutable structs as much as you can.






        share|improve this answer














        I have a readonly struct field in my class. This means that when I reference it, it references a copy and not the actual one, so when I call a change method, it will be working with a copy, and the original will remain unchanged.




        That's not at all what the readonly modifier does. The readonly modifier prevents you from assigning a new value to jk anywhere but in a constructor. Then, the static modifier allows you to reuse that value independently of the instance of Form1 you are working with.

        That said, neither readonly nor static is making the weird behavior you are describing because that exact behavior cannot be reproduced with the code you've posted.



        Look at a simpler example in a Console application (which you can try here):



        public class Program

        private readonly junk jk;
        private static readonly junk jk2;

        public static void Main()

        var program = new Program();
        program.jk.change();
        Console.WriteLine(program.jk.i); // prints 0

        jk2.change();
        Console.WriteLine(jk2.i); // prints 0



        public struct junk

        public int i;
        public void change()

        i += 1;




        Then, as @Damien_The_Unbeliever commented, try to avoid mutable structs as much as you can.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Mar 10 at 17:43









        Camilo TerevintoCamilo Terevinto

        19.7k64069




        19.7k64069





























            draft saved

            draft discarded
















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid


            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.

            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55090417%2freadonly-vs-static-readonly-clarification%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown






            Popular posts from this blog

            How to check contact read email or not when send email to Individual?

            Displaying single band from multi-band raster using QGIS

            How many registers does an x86_64 CPU actually have?