how to assign value to readonly static field - c#

I have a field which is static and readonly. The requirement is that the value should be allocated to the field at the login time and after that it should be readonly. How can i achieve this ?
public static class Constant
{
public static readonly string name;
}
Kindly guide.

If you declare a readonly field you can only set it in the constructor of the class. What you could do is implementing a property only having a getter and exposing a change method that is used during your logon sequence to modify the value. Other Parts of your program can use the property effectivly not allowing them to change the value.

public static class Constant
{
public static string Name
{
get
{
return name;
}
set
{
if (name == null)
name = value;
else
throw new Exception("...");
}
}
private static string name;
}

you need a static constructor
public static class Constant
{
public static readonly string name;
static Constant()
{
name = "abc";
}
}

Just assign the value in the declaration (or constructor) like this:
public static class Constant
{
public static readonly string name = "MyName";
}
readonly is sugar for the compiler, telling him, that you don't intend to change the value outside the constructor. If you do so, he will generate an error.

You can also create a static constructor in your static class
static Constant()
{
name = "Name";
}

Related

Expression-Bodied Function combined with Auto Properties results in problems

After finally upgrading to VS2015 and starting utilizing .NET4.6, I have been utilizing some of the syntactic sugar when I have come across old classes.
Unfortunately, this doesn't always go smooth :/ An example of this, is the following example.
I have this existing code that works.
private static string _bootstrapBundle;
public static string BootstrapBundle
{
get
{
return _bootstrapBundle;
}
}
A quick rewrite to use expression body gives me this, which works
private static string _bootstrapBundle;
public static string BootstrapBundle => _bootstrapBundle;
This can also be rewritten to use auto properties, like the following code which works
public static string BootstrapBundle { get; private set; }
If I try to take it a step further, and write the following, it doesn't work
private static string _bootstrapBundle;
public static string BootstrapBundle { get; private set; } = _bootstrapBundle;
All three examples of code compiles just fine, but when I later on try to assign a value like the following, it's only with the last piece of code that it fails to assign anything to BootstrapBundle.
BootstrapBundle = SquishIt.Framework.Bundle.Css()
.Add("/assets/stylesheets/Theme/" + theme + "/Bootstrap/bootstrap.less")
.Render("/assets/Cache/bootstrap.css");
How can this be? Are the expressions resolved differently? At different times? Am i abusing the syntax?
Let's go though the options you gave one by one and look at what each does:
private static string _bootstrapBundle;
public static string BootstrapBundle
{
get
{
return _bootstrapBundle;
}
}
I'm assuming that I don't have to explain what this does. But note that if you try to assign to BootstrapBundle, it will fail at compile time, since there is no setter. But you can work around that by assigning directly to the field.
private static string _bootstrapBundle;
public static string BootstrapBundle => _bootstrapBundle;
This is exactly the same as #1, only with more succinct syntax.
public static string BootstrapBundle { get; private set; }
Here we have an auto-property, that is a property with hidden (unspeakable) backing field. It compiles to:
private static string <BootstrapBundle>k__BackingField;
public static string BootstrapBundle
{
get
{
return <BootstrapBundle>k__BackingField;
}
private set
{
<BootstrapBundle>k__BackingField = value;
}
}
This means that setting the property now works and getting it after setting will give you the new value.
private static string _bootstrapBundle;
public static string BootstrapBundle { get; private set; } = _bootstrapBundle;
This is the same as #3, except that the hidden backing field is initialized to the value you gave:
private static string _bootstrapBundle;
private static string <BootstrapBundle>k__BackingField = _bootstrapBundle;
public static string BootstrapBundle
{
get
{
return <BootstrapBundle>k__BackingField;
}
private set
{
<BootstrapBundle>k__BackingField = value;
}
}
What this means is that there are now two fields: one hidden and one visible. The hidden field will initially be set to the value of the visible field (which is null), but after that, the two fields won't affect each other.
This means that if you set the property, and then get the property, you will get the updated value. But if you read the visible field, its value won't be updated. And vice versa: if you update the field, the value of the property won't change.
If you want the behavior to be exactly the same, you have these two options:
With expession body (like you offered, and with no other refactoring needed):
private static string _bootstrapBundle;
public static string BootstrapBundle => _bootstrapBundle;
With auto properties (like you also suggested, here you have to refactor all assignments to use the property rather than the field variable):
public static string BootstrapBundle { get; private set; }
The reason why your last example did not work, is that the field variable does not have a value when you try to assign it, where as using expression body, the getter is resolved every time you access the property, and assignment can be delayed. Put in other words, it works as readonly, and assignment of the variable has to happen inside a constructor, making the field variable useless, unless you want to use it for other methods (which would be completely unreadable and a terrible debugging experience!) :)
If you want your last example to work, you have to use a constant instead:
public static string BootstrapBundle { get; private set; } = "42";
but if you do not need the default value not much changes for you, and you might as well leave it out.
There are several ways of defining the property:
// this defines a public getter, public setter property with no backing field (there is an internal one, but not one you can access)
public static string BootstrapBundle {
get;
set;
}
// this defines a public getter, public setter property with a backing field
private static string _bootstrapBundle = "42";
public static string BootstrapBundle {
get {
return _bootstrapBundle;
}
set {
_bootstrapBundle = value;
}
}
//this defines a no setter property with a backing field
private static string _bootstrapBundle = "42";
public static string BootstrapBundle {
get {
return _bootstrapBundle;
}
}
using C#6 features:
// this sets a getter only property that returns the current value of _bootstrapBundle (equivalent to the last form in the code above)
private static string _bootstrapBundle = "42";
public static string BootstrapBundle => _bootstrapBundle;
// this sets up an auto property (no backing field) that at initialization gets the initial value of _bootstrapBundle
private static string _bootstrapBundle = "42";
public static string BootstrapBundle {get;set;} = _bootstrapBundle;
// equivalent to this:
public static string BootstrapBundle {get;set;} = "42";
Since you are setting the property in your code, it means you need a setter. If all what you wanted is a property with a backing field, you have no C#6 syntax to replace the good old return _backingField;/_backingField=value

Const set property in C# [duplicate]

This question already has answers here:
Is there a way of setting a property once only in C#
(14 answers)
Closed 8 years ago.
I have a variable in a class which must have a const value.
private string query;
The value of query can be set only after constructor call. The class is not a static class so there cannot be a Static Constructor with the variable being static readonly like usual. I was wondering can something like below be achieved
private string Query { get; const set;}
or
private string Query { get; static readonly set;}
so that my purpose is solved.
Or
Can I declare the variable normally as
private string query;
and then in the constructor I can make the variable query as const while initializing, i.e., dynamically.
Thanks in advance for any kind of help!!
A member variable/field can not be readonly if it's "set [only] after the constructor call". Neither const or static have any meaning in context of set - and less so than readonly, which still does not apply to properties.
The readonly keyword is a modifier that you can use on fields. When a field declaration includes a readonly modifier, assignments to the fields introduced by the declaration can only occur as part of the declaration or in a constructor in the same class.
One solution is to use a non-auto property with an explicit backing field and to honor read-only by contract. Other approaches include using a different pattern, including accepting the value in the constructor.
class Foo {
// Only allow this to be set ONCE after the constructor, BY CONTRACT
private string _query;
// No setter, can't assign "accidently"
string Query {
get {
if (_query == null) throw new InvalidOperationException("Query not set");
return _query;
}
// Or maybe just:
// get { return _query; }
}
// Call later on, BEFORE Query is used - but ONLY call once
void BindQuery (string query) {
if (query == null) throw new ArgumentNullException("query");
if (_query != null) throw new InvalidOperationException("Query already set");
_query = query;
}
}
Leveraging this answer...
https://stackoverflow.com/a/839798/342669
...you could
public class MyClass
{
private readonly _query = new WriteOnce<string>();
public string Query
{
private get { return _query.Value; }
set { _query.Value = value; }
}
}

Save Generated Random Numbers for later use

This following code will get me a random number:
Random r = new Random();
int srandom = r.Next(2147483647);
I want to save it to a string/int/long or some how so I will be able to use the same number. So for example if I call srandom now I will get random number but after a while it will change. I would like it to stay the same.
You can create a static field in your class, and initialize it once in the program lifecycle by setting it from the static constructor :
public class YourClass{
private static readonly int g_RandomInt;
static YourClass(){
g_RandomInt = new Random().Next();
}
public void InstanceMethod()
{
Console.WriteLine(g_RandomInt);
}
}
You can do the following:
Globals8.GlobalInt8 = Globals8.GlobalInt8.HasValue ? Globals8.GlobalInt8 : srandom;
And you declare the variable GlobalInt8 as a nullable int like this:
public static class Globals8
{
private static int? globalInt8 = default(int?);
public static int? GlobalInt8
{
get { return globalInt8;}
set { globalInt8 = value;}
}
}
The same thing can be applied to the long variable. What happens here that you initialize the value to the default value which is similar to null in reference object. After that you check if the variable has value then you ignore it. Else you set its value.
Hope this was useful.

C# Language Enum Declaration

Hi Is there a way to declare an enum or to customize the way of declaring an enum which returns an object in C#?
private enum testEnum
{
firstname =1
,lastname = 2
}
and if we want to return the names rather than 1 and 2 ?
like testEnum.firstname returns 1 .
I want to declare an enum to return objects like in Java . is it possible?
You can do this:
public class NameEnum
{
static NameEnum()
{
FirstName = new NameEnum("FirstName");
LastName = new NameEnum("LastName");
}
public static NameEnum FirstName { get; private set; }
public static NameEnum LastName { get; private set; }
private NameEnum(string name)
{
this.Name = name;
}
public string Name { get; private set; }
}
Is that close enough?
http://msdn.microsoft.com/de-de/library/system.enum.aspx
An enumeration is a set of named constants whose underlying type is any integral type except Char. If no underlying type is explicitly declared, Int32 is used. Enum is the base class for all enumerations in the .NET Framework.
You can use interfaces for this:
interface IColorEnum {};
class ColorEnum: IColorEnum
{
public static const Red = new ColorEnum();
public static const Green = new ColorEnum();
public static const Blue = new ColorEnum();
};
And use it like usual:
void foo(IColorEnum color)
{
if(color == ColorEnum.Red) {...}
}
Update+improve: you can even drop interface and just use class with couple of public static fields with type of this class and private constructor to prevent creating new instances of it:
class ColorEnum
{
private ColorEnum() {};
public static const Red = new ColorEnum();
public static const Green = new ColorEnum();
public static const Blue = new ColorEnum();
};
The docs state:
Every enumeration type has an underlying type, which can be any integral type except char.
Assuming you mean object to be complex/reference type. then the answer to your question is no. You could always create a class with named properties containing reference types.
I guess that you be a class exposing static fields that can then be of any type you want.
I think this is only possible in java.
It seems that you want to implement singleton the Joshua Bloch way.

Public Enumeration with only string values

I'm always confused which kind of enumeration I should use. A hashtable, an enum, a struct a dictionary, an array (how oldschool), static strings...
Instead of using strings in my code I want to use a beautiful enum like so:
public enum MyConfigs
{
Configuration1,
Configuration2
}
Problem is that I don't always want to convert my enum toString() as I'm not interested in the index representation of the enum.
What is the best way to represent a public enumeration of string based values?
In the end I would love to end up with using MyConfigs.Configuration1 where needed in my code.
I prefer defining "grouped" constants as static members of a dummy static class, like so:
public static class FieldNames
{
public const string BRANCH_CODE = "_frsBranchCode";
public const string BATCH_ID = "_frsBatchId";
public const string OFFICE_TYPE = "_frsOfficeType";
}
But of course they are not "enumerable" directly, so you can't foreach over them unless you provide a static array too:
public static string[] AllFieldNames
{
get
{
return new string[]
{
FieldNames.BRANCH_CODE,
FieldNames.BATCH_ID,
FieldNames.OFFICE_TYPE
};
}
}
public static class MyConfigs
{
public const string Configuration1 = "foo",
Configuration2 = "bar"
}
This is then pretty-much identical to how enums are implemented (ignoring the whole "it must be an integer" thing).
Type-safe enum pattern?
public class StringEnum
{
#region Enum Values
public static readonly StringEnum ValueOne = new StringEnum("Value One");
public static readonly StringEnum ValueTwo = new StringEnum("Value Two");
#endregion
#region Enum Functionality
public readonly string Value;
private StringEnum(string value)
{
Value = value;
}
public override string ToString()
{
return value;
}
#endregion
}
You can use this like:
private void Foo(StringEnum enumVal)
{
return "String value: " + enumVal;
}
If you never need to pass these values around in a type-safe manner to methods etc. then it is probably best to just stick with a constants file.

Categories