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

This question already has answers here:
variable that can't be modified
(9 answers)
Closed 5 years ago.
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.

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.

Related

Are properties just a simpler way of creating getter and setter? [duplicate]

This question already has answers here:
What are Automatic Properties in C# and what is their purpose?
(11 answers)
Closed 4 years ago.
I am learning about properties and I have a rather simple question:
Are properties just variables with "build-in" getter and setter?
What I mean can be described with this example.
int variable;
public void SetVariable(int _value)
{
variable = _value;
}
public int GetVariable()
{
return variable;
}
int variable { get; set; }
Are those two exactly the same or there is some slight difference that I don't see?
They are represented differently in the class. This is of practical importance if you use reflection, or if you use tools that use reflection. (You second example will show up in PropertyInfo, while your first would have to be found through FieldInfo plus MethodInfo plus application of some convention, a la bean conventions in Java.)
Because most developers most of the time don't deal directly with reflection, and because at best they don't think much about the indirect uses, it's easy to think of properties as just syntactic sugar around "field + getter + setter", but it can make a difference.
Edit: weirdly, when I initially answered I missed the (arguably) more important difference, which is how these things are used once declared. Yes you get (mostly) the same moving parts, but
In your first example,
variable = 37;
is a direct assignment that bypasses the setter logic. For this reason, it's likely you would declare variable as private and make the getter/setter public; so calling code would typically have to say
SetVariable(37);
instead.
In your second example, saying
variable = 37;
would call the variable's set method with the value 37.
Now again, this may seem meaningless since you're using the default setter in your example, but that needn't always be the case. It could be as simple as thread safety, or as complex as the value being transformed in some way rather than stored directly in an internal field.
And in the end you could still say it's syntactic sugar, but now it affects every bit of code that touches the variable, rather than just declaration of the variable itself.
In general, methods represent actions.
Properties represent data, Properties are meant to be used like fields, that meaning properties should not be computationally complex or produce side effects.
When it does not violate the following guidelines, consider using a property, rather than a method, because less experienced developers find properties easier to use.

var List<struct> Unknown type C# [duplicate]

This question already has answers here:
Implicit typing; why just local variables?
(6 answers)
Closed 8 years ago.
class A
{
A()
{
var x = 5; // this is allowed
}
var _x = 5; // the compiler is unhappy
}
I guess the compiler must be able to deduce the type for the member variable just the same way it does it for the local one. So what's the difference?
Eric Lippert answered your question right here: Why no var on fields?
Basically, for the general case it would require re-writing the C# compiler, as the way it currently does type inference would not work for cycles of var field variable assignments.
The var keyword was designed for anonymous types, which can only be used inside of a method.
Also, you're wrong; the compiler cannot always deduce a var field.
What happens if you compile the following:
class A {
public readonly var value = B.value;
}
class B {
public readonly var value = B.value;
}
This situation is impossible to recreate with local variables, since a variable cannot be referenced before it's defined.
The general problem here is that you're asking the compiler to consume type information while it's still generating that information.
Eric Lippert explains in greater depth.
I see two reasons:
It might be desirable to make the declaration of types in a public interface explicit
It's hard to implement. The C# compiler compiles in multiple phases.
At first it parses everything apart from method bodies so it knows about everything outside of function bodies. Then it can use that information to compile method bodies individually. What happens while compiling one method body hasn't much effect on what happens when compiling other method bodies.
If you could use var for fields the expression body of the field initializer would affect the type of the field and thus many other methods. So it doesn't fit the compiler design well.
This is a guess, but initialization of class-level fields must be done as part of the initialization (constructor) process for a Type, whereas initialization of a method-level variable happens when the method's stack frame is constructed. Perhaps the distinction is related to how these processes are compiled (how their implementation is created) inside the framework.

Why can we not set properties of properties?

I frequently find myself wanting to do something along these lines:
Form form = new Form();
form.ClientSize.Width = 500;
Of course the compiler will now complain that this code is not valid, since ClientSize is a property, and not a variable.
We can fix this by setting the ClientSize in its entirety:
form.ClientSize = new Size(500, ClientSize.Height);
Or, in general:
Size s = form.ClientSize;
s.Width = 500;
form.ClientSize = s; //only necessary if s is a value-type. (Right?)
But this is all looks unnecessary and obfuscated. Why can't the compiler do this for me? And of course, I'm asking about the general case, possibly involving even deeper levels of properties, not just the mundane example above
Basically, I'm asking why there is no syntactic sugar to translate the line form.ClientSize.Width = 500 into the above code. Is this simply a feature which hasn't yet been implemented, is it to avoid stacking of side effects from different getters and setters, to prevent confusion when one of the setters isn't defined, or is there a completely different reason why something like this doesn't exist?
Why can't the compiler do this for me?
It can. In fact, if you were programming in VB it would do exactly that. The C# compiler doesn't do this because it generally takes the philosophy of doing what you tell it to do; it is not a language that tries to guess at what you want to do and do that instead. If you tell it to do something silly, it'll just let you do something silly. Now this particular case is such a common source of bugs, and given these exact semantics is virtually certain to be a bug, so it does result in an error, because it's nice like that.
C# programmers learn to rely on the C# compiler never deciding to do something that you never told it to do, which can be a cause of confusion and problems when the compiler guess wrong about what you wanted to do.
I believe that you have a fundamental misunderstanding of .NET here. You can set properties of properties all day for class types because you're modifying the data of a reference without changing the reference. Take this code for example which compiles and runs fine:
class Program
{
public class Complex1
{
public Complex2 Complex2Property { get; set; }
}
public class Complex2
{
public int IntProperty { get; set; }
}
static void Main( string[] args )
{
// You must create instances of all properties to avoid a NullReferenceException
// prior to accessing said properties
var complex1 = new Complex1();
complex1.Complex2Property = new Complex2();
// Set property of property
complex1.Complex2Property.IntProperty = 7;
}
}
I assume your object is a struct or value type. The reason you can't do this for structs is that a struct is a value type - it gets copied around by value, not reference. So if I changed the above example to make Complex2 a struct, I could not do this line:
complex1.Complex2Property.IntProperty = 7;
Because the property is syntactic sugar for a get method which would return the struct by value which means a copy of the struct, not the same struct that the property holds. This means my change to that copy would not affect the original property's struct at all, accomplishing nothing except modifying a copy of my data that isn't the data in my property.
As for why the compiler doesn't do this for you? it definitely could, but it won't because you'd never want to actually do this. There's no value in modifying a copy of an object that you don't actually reassign to your property. This situation is a common error for developers who don't understand value vs reference types entirely (myself included!) and so the compiler chooses to warn you of your mistake.
For the compiler to allow myForm.ClientSize.Width = 500;, one of two things would be necessary: either the compiler would have to assume that the intended behavior is equivalent to:
var temp = myForm.ClientSize;
temp.Width = 500;
myForm.ClientSize = temp;
or else myForm would have to associate the name ClientSize with a method whose signature was:
void actupon_ClientSize<TParam>(ref Rectangle it, ref TParam param);
in which case the compiler could generate code similar to
myForm.actupon_ClientSize<int>((ref Rectangle r, ref int dummy)=>r.Width = 500, ref someDummyIntvar);
where someDummyIntVar would be an arbitrary value of type int [the second ref parameter would make it possible to pass parameters to the lambda without generating a closure]. If the Framework described a standard way for objects to properties to be exposed like that, it would make many types of programming safer and more convenient. Unfortunately, no such feature exists nor do I expect any future version of .NET to include it.
With regard to the first transformation, there are many cases where it would yield the desired effect, but also many where it would be unsafe. IMHO, there is no good reason why .NET shouldn't specify attributes which would indicate when various transformations are and are not safe, but they need for them has existed since Day One, and since the programmers responsible for .NET have consistently decided that they'd rather declare mutable structures to be "evil" than do anything that would make them be not evil, I doubt that will ever change either.

About unassigned variables

Just curious, I'm not trying to solve any problem.
Why only local variables should be assigned?
In the following example:
class Program
{
static int a;
static int b { get; set; }
static void Main(string[] args)
{
int c;
System.Console.WriteLine(a);
System.Console.WriteLine(b);
System.Console.WriteLine(c);
}
}
Why a and b gives me just a warning and c gives me an error?
Addionally, why I can't just use the default value of Value Type and write the following code?
bool MyCondition = true;
int c;
if (MyCondition)
c = 10;
Does it have anything to do with memory management?
Tim gives a good answer to your first question but I can add a few more details.
Your first question is basically "locals are required to be definitely assigned, so why not make the same restriction on fields?" Tim points out that Jon points out that it is actually quite difficult to do so. With locals it is almost always crystal clear when a local is first read and when it is first written. In the cases where it is not clear, the compiler can make reasonable conservative guesses. But with fields, to know when a first read and a first write happens, you have to know all kinds of things about which methods are called in what order.
In short, analyzing locals requires local analysis; the analysis doesn't have to go past the block that contains the declaration. Field analysis requires global analysis. That's a lot of work; it's easier to just say that fields are initialized to their default values.
(Now, that said, it is of course possible to do this global analysis; my new job will likely involve doing precisely this sort of analysis.)
Your second question is basically "Well then, if automatic assignment of default values is good enough for fields then why isn't it good enough for locals?" and the answer is "because failing to assign a local variable and accidentally getting the default value is a common source of bugs." C# was carefully designed to discourage programming practices that lead to irritating bugs, and this is one of them.
Because other variables are initialized with their default value.
Jon Skeet has already found some interesting words on this issue:
For local variables, the compiler has a good idea of the flow - it can
see a "read" of the variable and a "write" of the variable, and prove
(in most cases) that the first write will happen before the first
read.
This isn't the case with instance variables. Consider a simple
property - how do you know if someone will set it before they get it?
That makes it basically infeasible to enforce sensible rules - so
either you'd have to ensure that all fields were set in the
constructor, or allow them to have default values. The C# team chose
the latter strategy.
and here's the related C# language specification:
5.3 Definite assignment
At a given location in the executable code of a function member, a
variable is said to be definitely assigned if the compiler can prove,
by a particular static flow analysis (§5.3.3), that the variable has
been automatically initialized or has been the target of at least one
assignment.
5.3.1 Initially assigned variables
The following categories of variables are classified as initially
assigned:
Static variables.
Instance variables of class instances.
Instance variables of initially assigned struct variables.
Array elements.
Value parameters.
Reference parameters.
Variables declared in a catch clause or a foreach statement.
5.3.2 Initially unassigned variables
The following categories of variables are classified as initially
unassigned:
Instance variables of initially unassigned struct variables.
Output parameters, including the this variable of struct instance
constructors.
Local variables, except those declared in a catch clause or a
foreach statement.
The CLR provides a hard guarantee that local variables are initialized to their default value. But this guarantee does have limitations. What is missing is its ability to recognize scope blocks inside the method body. They disappear once the compiler translates the code to IL. Scope is a language construct that doesn't have a parallel in the CLI and cannot be expressed in IL.
You can see this going wrong in a language like VB.NET for example. This contrived example shows the behavior:
Module Module1
Sub Main()
For ix = 1 To 3
Dim s As String
If ix = 2 Then s = "foo"
If s Is Nothing Then Console.WriteLine("null") Else Console.WriteLine(s)
Next
Console.ReadLine()
End Sub
End Module
Output:
null
foo
foo
Or in other words, the local variable s was initialized only once and retains its value afterwards. This has a knack for creating bugs of course. The VB.NET compiler does generate a warning for it and has simple syntax to avoid it (As New). A managed language like C++/CLI has the same behavior but doesn't emit a diagnostic at all. But the C# language gives a stronger guarantee, it generates an error.
This rule is called "definite assignment". The exact rules are explained in detail in the C# Language Specification, chapter 5.3.3
Definite assignment checking has its limitations. It works well for local variables since their scope is very limited (private to the method body) and you can't get to them with Reflection. Much harder to do with fields of a class, it requires whole-program analysis that may need to reach beyond what the compiler can see. Like code in another assembly. Which is why the C# compiler can only warn about it but can't reject the code out-right.

Should I be using `this` by default? [duplicate]

This question already has answers here:
When do you use the "this" keyword? [closed]
(31 answers)
In C#, is "this" keyword required? [duplicate]
(6 answers)
Closed 9 years ago.
We all know that this refers to the actual instance of a class...but it seems to me that most people are not using it. So, should I be using it?
My thoughts about it are as follows: Since this refers to the actual instance of a class, it should be used to access any member of that class.
public void(String newValue) {
this.privateVariable = newValue;
}
This should guarantee that the value is not assigned to an object with the same name within the scope (which could also end up as undefined behavior, anyway). But, what if an underscore is used to separate private from non-private fields:
public voud(String newValue) {
_privateVariable = newValue;
}
this seems in that case a little redundant and unnecessary.
So, are there good reasons to use or not use this? Or am I just racking my brain about nothing?
Personally I only use it when it's necessary, e.g.
public MyClass(string name)
{
this.name = name;
}
I prefer that to renaming the parameter or field from the most natural name. I don't use this where it's otherwise unnecessary though. Having said that, there's absolutely no harm in doing so - and if you feel that it makes your code clearer, that's a very good reason to use it.
Nobody mentionned that you must use this if the requirement is to make a StyleCop compliant code and do not violate the readability rule SA1101. According to the documentation,
A violation of this rule occurs whenever the code contains a call to an instance member of the local class or a base class which is not prefixed with ‘this.’.
Also, in my opinion, using this keyword must be encouraged even for non-StyleCop-compliant source code, since specifying this increases readability and reduces the risk of mixing between local (method-scope) and class (object-scope) variables.
You should use the naming-convention approach. (The one with the undescore.)
There are dangers when changing code with the "this" approach if "this" is forgotten.
Why? If MyMethod in the followin class is later changed to include a local variable called "something" the compiler still compiles, while the code no longer does whats expected.
class MyClass
{
int something = 10;
void MyMethod()
{
//...lots'a code here...
something = 20; //Which var is something pointing at?
}
}
Changing it to the following will introduce a bug...
class MyClass
{
int something = 10;
void MyMethod()
{
int something = 0;
//...lots'a code here...
something = 20; //Which var is something pointing at?
}
}
So unless ALL developers working on your team, sharing code, always will remember "this"; don't go that way!
Personally I make sure that I never have name collisions between class members and locally declared variables. This means I never use this. However its all about readability really. If you think a "this" will make your code more intuitively understandable then use it, if not then don't.
I like using this. as it brings up intellisene which means I can quite often type a few letters of the method, variable and auto complete - makes writing code faster!
My two cents: Underscores are ugly!
=> fields are just camelCase
=> confusion with camelCase local variables is possible
=> always qualify with this
I used to use this all the time - probably a habit from pythons explicit self argument. I like to be reminded of when I use instance state.
Using Resharper from JetBrains made me brake that habit, since it would always flag this as redundant.
I use no special indicator for fields vs. locals (they are all ugly). I find that if it is getting harder to track which are which I'm better served by breaking up methods to be shorter with less local state. (The one exception is where the natural name of a parameter matches a field—most often occurs with constructors—then using this. to disambiguate.)
Edit: Added the one exception (thanks to other answers for reminding me).
It is subjective, but I prefer not to have it unless it provides unambiguity.
Using unnecessary this is like saying 'Create New Person'.
You choose :)

Categories

Resources