Replies: 3 comments
-
Actually more like #188: readonly int x = 4;
x = 5; // <- compile time error! There's also the mention of shorthand for combining val x = 4; // or maybe let
x = 5; // <- compile time error |
Beta Was this translation helpful? Give feedback.
0 replies
-
ITNOA I think this issue duplicate from #188. Apart from it I think |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
The task
Add a way to declare "variables" of a sort that can be introduced and used almost the same way as normal variables and at any place where normal variables can but can be only assigned once (though at any moment of run-time, unlikely to constants and read-only fields).
The problem
The C# language and the .Net Framework have already got a selection of immutable data types meant to protect data from unwanted changes and simplify some coding scenarios but using these only protects from modification of object instances, the variables storing references to them remain unprotected and the same variable of an immutable type can easily be found pointing to a totally different value some lines of code later after the initial immutable value has been assigned to it.
There also are constants and read-only fields implementing the required behaviour in its immutability part specifically but not in the other parts, their usage scope is limited and does not cover the scope of normal (though, in many cases, not meant to change after initialisation) variables usage sufficiently.
A solution example
In the Scala language (interestingly having a rather serious degree of similarity with C# but being somewhat more functional-oriented (though in considerably smaller degree than F# is) and targeting JVM rather than .Net as the primary runtime framework) the following will compile and mean exactly the same thing it means in C#:
`
// Valid: a variable declared and initialised with a runtime-calculated expression result
var a = someObject.SomeFunction(1);
// Valid: a new value legitimately assigned to the variable
a = someObject.SomeFunction(2);
`
but the following won't compile:
`// Valid: an immutable value declared and initialised with a runtime-calculated expression result
val b = someObject.SomeFunction(1);
// Compilation error: re-assigning to an immutable value (even of a reference type) is not allowed
b = someObject.SomeFunction(2);
`
A "val valueName = expression" declaration can placed everywhere where "var variableName = expression" can. The choice and format of the right-side (by the equals sign) expressions is the same for both cases, no special limitations/requirements in any (except the very fact the assignment can only take place once with "val..."). Semicolons are not necessary but can be voluntarily used in Scala so I've chosen to include them to let the code correspond C# more closely.
By the way, the "var variableName = expression" variable declaration syntax itself together with implicit type derivation had been introduced in Scala long before it was in C#, in exactly the same form (though optionally extendable).
As far as the "val" keyword is not used in C# as by now I think it is reasonable to consider "importing" it the same way "var" as been.
A probably re-usable (on the compiler code side) implementation existing in the C# compiler already
Though implementation of support of a duplicate of the "var" keyword enhanced by compile-time protection from re-assignments can seem trivial it may still be worth to point to an already-established feature of the compiler exhibiting behaviour similar to the desired (thanks to @quetzalcoatl at StackOverflow):
foreach iterator variable seems being protected by the compiler:
`
foreach(int x in Enumerable.Repeat(5, 1))
{
}
`
Motivation
As for me, in the majority of the cases I only assign values to my variables once (I only mean those declared inside function bodies, however, class fields and properties are a somewhat different story and there are established ways to protect them from unwanted modifications already) so re-assignment is usually something that is not meant to happen which means a thing that is not expected and can become a cause of a bug this way. I believe introduction of the feature described above and proposing it as a recommended way to declare variables that don't need to be re-assigned as by the application logic can increase general C# code reliability and ease of debugging.
Beta Was this translation helpful? Give feedback.
All reactions