I suggest you ...

Allow readonly modifier on local variables, not just properties.

Readonly modifiers shouldn't be canned for just instance-level properties on a class. Readonly isn't always to explicitly prevent subsequent code from changing a value. I would argue readonly modifiers can significantly improve code comprehension and readability:

Imagine the following code in a method definition, where prod_count would be a local:

int prod_count = (List<Product>) prods.Count;

If the compiler would allow this:
readonly int prod_count = (List<Product>) prods.Count;

All of a sudden, I know as a developer reading the code that I don't have to scan for prod_count getting reassigned to something...I can mentally write it off as, okay that's just the count, I don't have to scroll up or down in the code to see if something is reassigning a value to it.

200 votes
Vote
Sign in
Check!
(thinking…)
Reset
or sign in with
  • facebook
  • google
    Password icon
    I agree to the terms of service
    Signed in as (Sign out)
    You have left! (?) (thinking…)
    Raymond Nirnberger shared this idea  ·   ·  Flag idea as inappropriate…  ·  Admin →

    13 comments

    Sign in
    Check!
    (thinking…)
    Reset
    or sign in with
    • facebook
    • google
      Password icon
      I agree to the terms of service
      Signed in as (Sign out)
      Submitting...
      • Dylan Nicholson commented  ·   ·  Flag as inappropriate

        readonly products = GetProductList();
        getOrders().ForEach(o => o.UpdateProductsInformation(products));

        There's no guarantee the actual items in the products list won't get changed - just that 'products' is still referring to the same list, so the use of 'readonly' here would potentially be misleading. The guarantee that products still points to the same list is given by the C# convention of pass by value.

        Having said that I do like the idea of local readonly "named values" ('variables' would be seem to be an obvious misnomer - I gather they're called 'bindings' or bound identifiers in F#).

      • Андрей Смирнов commented  ·   ·  Flag as inappropriate

        Часто требуется быть уверенным в том, что некоторые локальные переменные и параметры метода не изменяются. Также, это повышает читаемость кода. Не вижу ни каких препятствий и сложностей в реализации данной возможности. С нетерпением ждём появления этой возможности в очередном обновлении или версии VS !!!

        В языке C++ аналогичная возможность уже присутствует, например:

        void M(int a, const int b)
        {
        const int c = ...;
        int d = ...;

        a = ...; // OK
        b = ...; // error!!!
        c = ...; // error!!!
        d = ...; // OK
        }

      • Richard Gibson commented  ·   ·  Flag as inappropriate

        I also support this, as part of a general move in the language to supporting immutability. I would like to see a "val" keyword, such as those in Scala and Swift.

        They could actually use "let", because that is already a keyword in C# (use it in Linq expressions) and would align with the keyword's usage in F#.

      • Raymond Nirnberger commented  ·   ·  Flag as inappropriate

        @palak chokshi....

        I happen to know how to use an IDE thank you very much, and I'll concede Visual Studio's "Find All References" feature is the best I've seen in any IDE. In fact, Visual Studio itself is probably hands-down the best IDE there is.

        It may be true that the find all references feature would work here, but again, the point is to make code comprehension simpler by not having to click find all references or scroll up or down inside the editor. If I can skip the step of a mouse-hover, right-click, and left-click, that gives me more productivity. The scenario that I describes above is simple and contrived, but image you're interested in more than one item. Assuming we're talking about find all references that appears in the Find Symbol Results window...only one result page can be opened at a time. As soon as we're interested in more than one item...it becomes challenging. I don't think the solution is to allow find all references to be shown in multiple tabs.

        "Seems like you want this feature for something for which there is a handy workaround available."

        By calling it a workaround, isn't that half-admitting you see value in my feature request? In general, I think IDEs tend to change the way we code (ex: Hungarian notation is now a moot point), but I don't think they should influence the types of features that are available in a language.

      • Raymond Nirnberger commented  ·   ·  Flag as inappropriate

        FYI in the past there was talk about the CLR not having support for this...but if F# can provide runtime immutability, why does C# have to be a second class citizen?

        FYI Google Dart supports "final" modifiers on locals....

      • Palak Chokshi commented  ·   ·  Flag as inappropriate

        And why wouldn't you want to just right click prod_count and click Find All References to see if the variable has been reassigned to something else or not? Seems like you want this feature for something for which there is a handy workaround available. why clutter the language for this?

      • Jason WIlliams commented  ·   ·  Flag as inappropriate

        Agreed.

        * You should not need to declare a readonly value at class scope if it is only used in a single member - it needs to be a local constant.
        * Method-scope "constants" are often calculated values so they *can't* be placed at class scope

        e.g.
        double sinAngle = Math.Sin(angle);
        sinAngle = Math.Cos(angle); // oops, I meant to assign this to cosAngle

        This helps to clarify and protect code where values need to be precalculated and must not change during the calculation that follows, and it is my most-missed feature of C++.

        And it would be an "easy" feature to add as it only impacts the compiler - within the method body this variable cannot be written to again.

      • Mika Karjunen commented  ·   ·  Flag as inappropriate

        We should not only have read only variables, but also read only parameters. There is no point in changing the values of the method parameters inside the method. Also I also agree with read only variables. It's just that you should not write that long methods that following your own logic requires such a feature. Therefore altough I am totally for the idea of read only variables, I think that C# team has more important things to look at.

      • Joshua A. Schaeffer commented  ·   ·  Flag as inappropriate

        "const" already means "compile time", so my vote would be with "readonly". This feature would keep you in good behavior while writing the rest of the method in question. I would say we should also allow "readonly" with method parameters, which are after all on the same stack as local variables.

        readonly int customer = customers.First();

      • Anonymous commented  ·   ·  Flag as inappropriate

        For readonly locals the syntax should be something like this:
        val customer = customers.First();

      • Richard Creamer commented  ·   ·  Flag as inappropriate

        I agree with the suggester. The 'const' keyword does not allow a local variable to be assigned a non-constant value (e.g. an expression such as DateTime.Now.Millisecond) and I agree that these semantics are appropriate for 'const'.

        Since 'const' cannot fill this role, extending 'readonly' to fill this role would be helpful.

        For example, the 'final' keyword in Java allows a developer to declare that a variable (method parameter, local variable, instance variable) will immutable after assignment. This is a nice way to ensure a future developer doesn't inadvertently change its value and would probably come in handy in a multithreaded execution environment.

        I think it would be a nice addition to C#.

      Feedback and Knowledge Base