How do I declare an immutable variable (value) in C#? [duplicate]

若如初见. 提交于 2019-12-10 19:11:52

问题


In Scala I can write (and it will mean exactly the same thing it means in C#)

var v = 1;
v = 2;

but can't write (well, of course I can write but can't compile actually though the syntax is correct)

val v = 1;
v = 2;

Semicolons are not necessary but can be voluntarily used in Scala so I've decided to include them to let the code correspond C# more closely. val means an immutable value, a kind of a variable that can be only assigned once but, unlikely to c# consts can be initialized with a result of a run-time expression, unlikely to C# readonly fields can be introduced at any place in the code where a var variable can and, unlikely to C# immutable types is immune to a reference replacement, not just modification of the referenced object.

I enjoy the way C# introduces more and more functional coding candies in every new version of the language but miss this (arguably the most simple and the most essential) one heavily. In the majority of the cases I only assign values to my variables once so re-assignment is usually something that is not meant to happen which means a thing that is not expected and can cause a bug this way. Might I, perhaps, just be unaware of such a feature? I don't mind such a declaration looking a little bit clumsy (some F# imports perhaps, whatever they might look like in C# code).

UPDATE: As it seems there indeed is no such a feature a by now (March 2017, C# language version 7.0) and as suggested by others I have submitted an issue at the C# language design GitHub repository.


回答1:


Basically, you can't - at least at the time of C#6 - with one notable exception mentioned below. Maybe something will change in future versions of C#. There were plans for "record types" for C# 7, it could open some way when paired with anonymous inline objects. However, I actually don't know what gets exactly added in C#7.

The only normal support for anything like that is at class member scope:

class Foo
{
    public readonly int shoeSize; // readonly field
    public int ShoeSize { get { .. } } // readonly property
    public int ToeSize { get; } = 5; // readonly property with initializer
    // ..etc
}

with read-only field being settable only during object member initialization or in constructor, and getters - well, should be more or less obvious.

At the scope of normal code, any 'variable' (as opposed to 'member' above, or 'constants' you mentioned) you create is (almost) always writable, and assignment semantics will always differ depending on the kind (struct/class) of the variable's type.

EDIT: I've found one! Your note about clumsy syntax got me an idea. Actually, the foreach iterator variable is guarded against assignments by the compiler, so you can use it with Enumerable.Repeat to quickly open a foreach scope that will iterate just once..

static void Main()
{
    foreach(int x in Enumerable.Repeat(5/*value for X*/, 1/*single run*/))
    {
        x=4;   // <- compile time error!
        Console.WriteLine(x);
    }
}

EDIT2: another option, nicer, tuple literal that is said to be added in C#7

public static void Main()
{
        var pair1 = (42, "hello");
        System.Console.Write(Method(pair1).message);

        var pair2 = (code: 43, message: "world");
        System.Console.Write(pair2.message);
}

fields/properties of a Tuple are not writable, hence such tuple-literal will be quite handy, except for the 'pair2' extra identifier to write (and .. some cost of creating and disposing a tuple object)

However, I actually don't know if they are mutable or not. They are called "tuples", so I immediately think of "Tuple<>" whose properties are readonly, but then, in this old article

Tuples are value types, and their elements are simply public, mutable fields.

Now, I don't (yet) have VS2017 installed.. It will take some time, maybe someone else will be able to check that sooner than me.



来源:https://stackoverflow.com/questions/42916260/how-do-i-declare-an-immutable-variable-value-in-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!