How to make a variable (not class member) "read only" in C# - c#

I'm new to the C# world and I can't find a method to declare read only variable in C# (something like declaring "const" variable in c++). Is there one?
I'll give you an example:
...
int f() { return x; } // x is not const member
...
void g() {
int readOnlyVar = f(); // is there a method to declare readOnlyVar as read only or const
// Some code in which I want to restrict access to readOnlyVar to read only
}

There isn't an identical analogue.
The readonly keyword allows the variable value to be mutated, but only in a constructor.
The const keyword means the value cannot mutate and needs to be a compile time constant and can only be one of the following types: sbyte, byte, short, ushort, int, uint, long, ulong, char, float, double, decimal, bool, string, an enum-type, or a reference-type. (C# 4.0 spec §10.4).
And in c#, readonly only applies to fields and cannot be applied to local variables.

No, there exists no solution for your code-example.
const in C# is for compile-time constants and since your variable gets its value from a function, it's not known at compile-time.
The readonly keyword does kind of what you're looking for, but that's only for member variables in classes (and only allows variables to be set in the constructor of the class).
But, on the other hand, why would you ever need it? If your function is very long, it should be refactored into smaller functions. If it's not very long, then why would you need to enforce a rule like this? Just don't assign to readOnlyVar is probably my best suggestion for you I'm afraid.

There are two ways to set a variable as read only.
public class ClassA
{
private const int I = 5;
private readonly int J = 5;
}
The const keyword will set the value at compile time. The readonly keyword will set the value at construction. So, if you need different values for each instance, use readonly. Otherwise use const.

in c# we having const or readonly keyword to declare a constant.
const
A constant member is defined at compile time and cannot be changed at runtime. Constants are declared as a field, using the const keyword and must be initialized as they are declared. For example;
public class MyClass
{
public const double PI = 3.14159;
}
PI cannot be changed in the application anywhere else in the code as this will cause a compiler error.
readonly
A read only member is like a constant in that it represents an unchanging value. The difference is that a readonly member can be initialized at runtime, in a constructor as well being able to be initialized as they are declared. For example:
public class MyClass
{
public readonly double PI = 3.14159;
}
or
public class MyClass
{
public readonly double PI;
public MyClass()
{
PI = 3.14159;
}
}
Because a readonly field can be initialized either at the declaration or in a constructor, readonly fields can have different values depending on the constructor used. A readonly field can also be used for runtime constants as in the following example:
public static readonly uint l1 = (uint)DateTime.Now.Ticks;
Notes
readonly members are not implicitly static, and therefore the static keyword can be applied to a readonly field explicitly if required.
A readonly member can hold a complex object by using the new keyword at initialization.
readonly members cannot hold enumerations.
credit goes here:
http://www.dotnetspider.com/forum/69474-what-final-c-i-need-detailed-nfo.aspx

This is not a language feature, but you’re not the only person interested in such a feature. You do have some options, though. You might replace your method’s implementation with a class that has readonly member variables. This is a big pain, though, and really explodes the size of your code. (When you write lambdas or use async methods, C# does something similar to lift locals to class fields and turns your lambda or async method into methods on an autogenerated class. We are basically doing the same thing, but manually so that we can set readonly.)
class Scope
{
int x;
int f() => x; // x is not const member
void g()
{
new gImpl(f()).Run();
}
class gImpl
{
readonly int readOnlyVar;
public gImpl(
int readOnlyVar)
{
this.readOnlyVar = readOnlyVar;
}
public void Run()
{
// Some code in which I want to restrict access to readOnlyVar to read only
// error CS0191: A readonly field cannot be assigned to (except in a constructor or a variable initializer)
readOnlyVar = 3;
}
}
}
Another alternative which requires less code but is still clunky is to abuse a feature of foreach. The foreach keyword does not let you assign to the iteration variable. So you could do something like this:
class Scope
{
int x;
int f() => x;
void g()
{
foreach (var readOnlyVar in new[] { f(), })
{
// Some code in which I want to restrict access to readOnlyVar to read only
// error CS1656: Cannot assign to 'readOnlyVar' because it is a 'foreach iteration variable'
readOnlyVar = 3;
}
}
}
The foreach method makes it easier to use anonymous types, but you could use generics combined with type inference to use anonymous types with the class method.

Related

Why the C# compiler forces explicit initialization of all value type's fields in the constructor?

For a class, this is OK:
class Point
{
private int _x, _y;
public Point(int x)
{
_x = x;
}
}
But if I use a value type the compiler complains that the _y is not initialized:
struct Point
{
private int _x, _y;
public Point(int x)
{
_x = x;
}
}
I'm wondering what's the rationale behind this? Why can't the compiler just initialize _y to 0 as it does when there is no explicit constructor is provided?
Why? Because the language specifiaction (ECMA 334 16.4.9) says so:
No instance function member (including the set accessors for the properties X and Y) can be called until all fields of the struct being constructed have been definitely assigned. Note, however, that if Point were a class instead of a struct, the instance constructor implementation would be permitted.
As for why the language specification demands it... presumably to make struct assignment as cheap as possible by avoiding an unnecessary wipe and overwrite.
This can be found in Section 5.3.1 of C# spec which states that the following types of variables are initially assigned. The list for the purposes is:
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.
The following will give you a value of 0:
Point p = new Point(10);
Console.WriteLine(p.y);
As the variables are initialized to their default values which can lead to bugs in code, the compiler warns on uninitialised variables.
This by itself won't compile:
int temp;
Console.WriteLine(temp);
Jon Skeet has a good answer here:
Non initialized variable in C#
You can do it like this, now all value types are initialized:
struct Point
{
private int _x, _y;
public Point(int x)
:this()
{
_x = x;
}
}
Note, I simply called the default constuctor.
I think the reason for this behavior is, that if you either call the default constructor or specify all fields in your constructor with parameters, it shows, you know what you're doing and not accidental initialize some fields to default.

What is the real difference between a static member and a constant in C#?

I'm learning C#,and now i'm trying to understand static members and constants.Which is the best way to declare a constant?
This way?
class Myclass
{
public const double G=9.8;
}
Or
class Myclass
{
private static double G{get;set;}
static MyClass()
{
G=9.8;
}
}
I've asked this question because,with the 2 ways i access the membre with the same code:
Console.WriteLine(Myclass.G);
constant:
Constant fields are defined at the time of declaration in the code
snippet, because once they are defined they can't be modified. By
default a constant is static, so you can't define them static from
your side.
It is also mandatory to assign a value to them at the time of
declaration otherwise it will give an error during compilation of the
program snippet. That's why it is also called a compile-time constant.
Explanation:
Consider ff. code:
void Sum(int j)
{
const int i = 9, k = 2;
const int A = i + k;
}
This will produce a result of 11, without showing any error since we already declared it at the initial point of declaration.
But how about:
void Sum(int j)
{
const int i = 9, k = 2;
//const int A = i + k;
Const int B = i + j;
}
This code snippet will take you toward a compile-time error, because there is no initialization, since it's evaluated at run time.
Points to Remember
Compile-time constant
Can't be declared static
Can't be modified or changed
Can be of any type of Access Modifier
Local scope
Needs to get initialized
Declared at the time of declaration
Static
The static keyword is used to declare a static member. If we are
declare a class as a static class then in this case all the class
members must be static too. The static keyword can be used effectively
with classes, fields, operators, events, methods and so on
effectively.
Consider ff. code:
class ReadOnly
{
static int i = 11;
public static void disp()
{
Console.WriteLine(i);
}
}
Explanation:
This code will show no error and produce a result (11), since we declared its value to be static at the time of declaration. So we can access it depending on our use in the program.
But how about this:
class ReadOnly
{
int i = 9;
public static void disp()
{
Console.WriteLine(i);
}
}
This snippet above will show an error, because we didn't declare a value for the static and we are trying to access it within a method. We can't do that.
Points to Remember:
Can't be used with indexers
Works with constructors too
By default it is private
Can be parameterized or public too
If its applied to a class then all the class members need to be static
You can read more about above explanation here: constant vs readonly vs static
Additional note for static methods.
Consider ff. code:
public class SomeClass {
public string SomeMethod() {
return "Hello, World.";
}
}
When you want to Access SomeMethod of SomeClass, you need to instantiate SomeClass first:
var some = new SomeClass();
string result = some.SomeClass(); //this will set result as "Hello, World."
Compared to a static method:
public class SomeClass {
public static string SomeMethod() {
return "Hello, World.";
}
}
When accessing SomeMethod, you don't need to instantiate SomeClass. You can access it directly by:
string result = SomeClass.SomeMethod(); //this will give "Hello, World."
Which is the best way to declare a constant?
Its not the best, its the only way: const double G = 9.8;.
Or (...) static double G { get; set; }
Thats not a constant! Constant means constant: 1 is a constant, 'c'is a constant, PI is a constant... they represent values that don't change, ever!. Your second implementation of G can change, therefore its not a constant.
Also, its important you notice that constants are known at compile time, there is no evaluation needed at runtime.
This is the reason why any reference type const (expect string which has specific compiler support through string literals) can only be initialized to null, any other option would need to be evaluated at runtime.
Its also the reason why only a finite set of value types can be declared as const too. All of them are existing types in the framework and.. surprise, surprise, they all have compiler literal constant support: 1, 'c', 9.8 or 0.25M but not 01/01/2017 (how else would the compiler know the values before runtime?).
Another interesting question you didn't make is: what about static readonly?
You can think of static readonly as "the poor man's" const. Its often used to circumvent the limitations const offers concerning what types and initializing values are allowed.
It is almost the same as a constant, but there are a few important and decisive differences:
It can change; although it is readonly, you can change it's value inside the static constructor of the declaring type. const can never change after initialized.
It is evaluated at runtime, not compile time as a true const.
Any type can be declared as a static readonly and initialized to any valid value as you would do with any regular field.
As a nittpicking side note, you shouldn't make G a constant ;). It changes, and quite a bit. G in Ecuador is different from G in the North Pole.
const variables are assigned values at time of definition.
They are available at compile time. You can even use a compile time evaluate-able expression at compile time. But once a value has been assigned to a const variable, it cannot be changed at any other time.
Using static field means the value will remain same for every user of the application, but this value can be changed by code in any of the classes, and it will change for every user of the application.
Do not use static for constants, use const only. const are by default static, and you cannot use static keyword with it.
Check this
void Main()
{
// You will not be able to change value for const variable.
Console.WriteLine(Myclass.G);
// You will be able to change value for static variable,
// and this change will impact all users of the application.
// For every user, this field will store value of 10 now.
// That will not be required or desired code behavior.
Myclass1.G = 10;
Console.WriteLine(Myclass1.G);
}
// Normal class with const field
class Myclass
{
public const double G=9.8;
}
//static class with static constructor
static class Myclass1
{
public static double G{get;set;}
static Myclass1()
{
G=9.8;
}
}
Read More
Here you are talking about two different things, and this is their definition from MSDN:
1- static modifier: To declare a static member, which belongs to the type itself rather than to a specific object. The static modifier can be used with classes, fields, methods, properties, operators, events, and constructors, but it cannot be used with indexers, finalizers, or types other than classes.
2- const keyword: To declare a constant field or a constant local. Constant fields and locals aren't variables and may not be modified. Constants can be numbers, Boolean values, strings, or a null reference. Don’t create a constant to represent information that you expect to change at any time.
So a static member is defined for a Class (for all its instances, and that's why you can access it directly from the name of the Class) but can be modified. a const field of class can not be modified.

C# getter vs readonly

Is there any difference between the following?
class C
{
// One:
public static readonly int ValueAsAMember = 42;
// Two:
public static int ValueAsAProperty { get { return 42; } }
}
I'm used to writing constants the first way (unless they're private/internal, in which case I use the const keyword), but I recently saw the second form.
Is there any advantage one way over the other in terms of readability, convention, performance, or anything else?
You have three choices:
public static readonly int Value = 42;
public static int Value { get { return 42; } }
public const int Value = 42;
Choose static readonly if the value will not change at runtime but might change in future versions of your code.
Choose a property if the value might change at runtime. Of course it won't change if you use the given code.
Choose const if the value is really a constant that will not even change in future versions (something like Math.PI or int.MinValue). And of course the use of const is limited by the type of the value.
The difference between const and static readonly is that the const value will be replaced on the call site. If you change the value of a const in a future version then all assemblies that rely on your class need to be recompiled using the new value.
The property requires a method call (calling a getter is a method call). So if the value is constant at runtime there is no need for that.
Yes, there is an advantage:
If the value gets changeable at any point in the future (e.g. in a future version of your code), in a way that it is, for example, time-dependent, you can support that in the read-only property without changing the public interface of your class.
If you have to replace a readonly field with a property, you will have to recompile any other assemblies that use your class.
There are two major differences:
The first is that fields cannot be on interfaces, whereas properties can. So if you want to use this in an interface, you have to use the property.
The second, more interesting, is that readonly fields CAN be modified, while the object is being constructed. Take the following code:
public class MyTestClass
{
public readonly int MyInt = 1;
public MyTestClass()
{
MyInt = 2;
}
}
If a caller does
new MyTestClass().MyInt
they will get 2. The same goes for static constructors for a static readonly field.
The way I see it, using the first way describes the intention of the value better - which is that it is immutable. When a person is looking at the class' interface, he will see that the value is read-only, and won't have to wonder whether it can be changed later (since in the second case he can't see the property's implementation).
An important thing to note about const declarations (I don't believe it's true for readonly) is that changing the field's value constitutes an API change, even if you're just changing the value from 42 to 41. The reason is that for consts, the value is determined during compile time, which means that if I compile a module that uses your constant, and you later change it, I will still be using the old value until I recompile my module with your new version.
readonly is nice to use on things that can only be changed in your constructor. Examples of this is typical services as interfaces when you are following the TDD pattern.
In your example const is best, it's a constant after all.
readonly
const
Cheers
I think the first line making something constant or rather readonly using readonly keyword.
and the second line is making use of a property to implement readonly. Both do the same but if you compare with the IL the property would add few extra lines of code to the dll.
The main advantage for me is with readonly you are allowed to declare it anywhere in your code. But, you will get a chance to set it only once. With the setter, you declare and set in one stroke.
Yes, there's a difference between the two.
A readonly field can only be set in the constructor.
A {get; private set;} can be set at anytime from within the class.
Example:
public class Car
{
public readonly string Name;
public string color {get; private set;}
public Car()
{
Name = "Car";
Color = "Red";
}
// will fail compilation
public void ModifyName()
{
Name = "Subaru"
}
// perfectly ok
public void ModifyColor()
{
Color = "Green"
}
}
A Property is just syntactic sugar around a field, a property without a setter is simply declared a readonly field so the compiler will allow you to set it at runtime in the constructor, because to the compiler you are referencing a readonly field. There is a larger discussion around what to use a field or property, which is not within the scope of the question. And yes its this syntactic sugar that you have to do the recompiling referenced by #SOreadytohelp. Just to be clear a property is a field with a get and set method created for it, C# will allow you to reference it like a field rather than doing an annoying call to the getter or setter everytime.

Struct default constructor still be used despite overriding it

I have the following code :
struct Person
{
public readonly int x;
public Person( int x )
{
this.x = x;
}
}
class Program
{
static void Main(string[] args)
{
Person p = new Person();
Console.Write(p.x);
}
}
This code work well.Why? Did overriding default constructor not be applied to structs ?
Did using a parameterized constructor override the default one or not ?
You didn't override the default constructor; you just provided an overload which accepts one parameter. Unlike classes, having a parameterized constructor for a struct doesn't mean that the default constructor won't be automatically generated. The C# compiler automatically provides a default, parameterless constructor for structs, and it does not allow you to override it with your own.That's simply the nature of structs.
From Using Structs (C# Programming Guide)
It is an error to define a default (parameterless) constructor for a struct. It is also an error to initialize an instance field in a struct body. You can initialize struct members only by using a parameterized constructor or by accessing the members individually after the struct is declared. Any private or otherwise inaccessible members can be initialized only in a constructor.
If you really want to require users of your data type to call a custom constructor, you'll have to use a class instead.
Structs will always have a default parameterless constructor which you cannot overrride.
MSDN explains a little. This (and other) limitations are there because structs are value types. If you need to use them like objects, use objects :)
http://msdn.microsoft.com/en-us/library/aa288208%28v=vs.71%29.aspx
Structs cannot contain explicit parameterless constructors. Struct members are automatically initialized to their default values
Some good explanation
Why can't I define a default constructor for a struct in .NET?
In your code, you are not calling the constructor you created, but rather the default constructor.
To call the constructor you overrode, try the following code:
struct Person
{
public readonly int x;
public Person( int x )
{
this.x = x;
}
}
class Program
{
static void Main(string[] args)
{
int v = 9;
Person p = new Person(v);
Console.Write(p.x); // will output '9'
}
}

Achieving Local Runtime Immutability in C#

I currently know of two ways to make an instance immutable in C#:
Method 1 - Compile Time Immutability
void Foo()
{
// Will be serialized as metadata and inserted
// as a literal. Only valid for compile-time constants
const int bar = 100;
}
Method 2 - Readonly Fields
class Baz
{
private readonly string frob;
public Baz()
{
// Can be set once in the constructor
// Only valid on members, not local variables
frob = "frob";
}
}
It would be nice to have a guarantee that, some instance, once instantiated, will not be changed. const and readonly do this to a small degree, but are limited in their scope. I can only use const for compile-time constants, and readonly for member variables.
Is there any way to give a local variable immutability after its initial instantiation (the way readonly works, but on a more general level)?
Scala does this with the var keyword, which declares a new immutable value, which cannot be reassigned to after it gets its initial value:
var xs = List(1,2,3,4,5) // xs is a value - cannot be reassigned to
xs = List(1,2,3,4,5,6); // will not compile
You can't prevent variables from being re-assigned in C# with the exception of fields, by as you have already mentioned using const or readonly.
You could make your own immutable version of any existing mutable type by wrapping it or if it's your own class, re-write it to be immutable but you can't achieve it for variables in a method which is what your question seems to be getting at.
F# has a few options for immutability (the 'let keyword if I'm remembering correctly) that C# doesn't so it might be worth looking at F# if you still want to leverage the power of .NET but with complete immutability.
If the wrapper is static it cannot be overwritten. This does sacrafice compile time checking on variable names and type safety.
public static class ReadOnly
{
private static readonly Dictionary<string, object> values = new Dictionary<string, object>();
public static bool SetValue(string name, object data)
{
if (values.ContainsKey(name))
return false;
values[name] = data;
return true;
}
public static object GetValue(string name)
{
return values[name];
}
}
ReadOnly.SetValue("xs", 1);
ReadOnly.SetValue("xs", 1); // will crash

Categories

Resources