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.
Related
I currently am unable to use a variable that is a string to Add as an item to a list. It simply returns null when I pull the list later:
public class JobStatus
{
public static string _JobURI;
public static string currentStatus = "no job";
public static void checkStatus()
{
...
//define job URI
List<string> jobURIs = new List<string>();
jobURIs.Add(_JobURI);
However, when I insert a string value like below instead of a variable, it adds it properly to the list:
//define job URI
List<string> jobURIs = new List<string>();
jobURIs.Add("new item name");
I'm not sure what I'm missing.
Based on your posted code, the reason you are getting null for _JobsURI is that you declare it here:
public static string _JobURI;
But you never assign it a value. Per the documentation: "A string that has been declared but has not been assigned a value is null."
Try assigning a value to _JobURI and then adding it to the List<string>:
public static string _JobURI = "Some string here.";
I figured it out, beginning programmer mistake. I used the Get Set method in the same class and declared the variable as well you all suggested above:
public static string currentStatus = "no job";
private static string joburi = "";
public static string JobURI
{
get { return joburi; }
set { joburi = value; }
}
Thank you for your help.
I use the following dedicated class to manage session variables in my applications (ignore misspelled names; that's intentional):
This first code block is for usage. You can see the class it is calling on, at the next code block
//'importing' the class for current project
using SeSn = Debug_Tests.Seseions.SeSn;
// creating an object (usually with name related to currentProject)
public static SeSn.CreatCurrentSesionVariablsStructNamed CurSesVarStruct = new Seseions.SeSn.CreatCurrentSesionVariablsStructNamed();
// the long name helps me in this little 'chaos'
This is an instance of a struct, that is 'grouping' or 'tying' all my globals into one bundle. Whenever I may need to store my global variables, I will assign the values into the appropriate-struct-variable that CurSesVarStruct has to offer.
Then all I need is to access session variables once, only to extract the "Variable-collection" -object, ... as it is actually a session variable that I keep its name constant - _CurrentSesionGlobals.
In short, it's the struct that is stored in the session as one of the session variables - data type = object, or you could say a clone of the struct to be saved between sessions.
Since I have that and can use it with _CurrentSesionGlobals, I could just access any value I need from session through the following, for example:
Assign the struct before storing it in Session:
CurSesVarStruct.SelectedUercustid = custID;
Then the next method - ExtrctSesnVar() below, allows me to use for example:
Extract a variable that was saved in last session:
custID = ExtractSesnVar().SelectedUercustid;
So SelectedUercustid is actually one of the struct members.
The Question/Problem
Performing extraction of _CurrentSesionGlobals out of the session variables.
public static SeSn.CreatCurrentSesionVariablsStructNamed ExtrctSesnVar()
{
var CurrAppGlobals = SeSn.GetValueAS.ACloneOfTheStructObj("_CurrentSesionGlobals");
return (SeSn.CreatCurrentSesionVariablsStructNamed)CurrAppGlobals;
//the question is refereing this location.
}
How can I have a return value for a null result, or a condition that will first ask if the object / a given Session Variable, that I am trying to extract isn't null, or does not exist?
Currently there's an exception error while I am trying to get the value of a non-existing session variable.
The next code block is a class that I add into the solution, as a helper to every website application. It's actually a namespace, so the class that is responsible to handle session variables is Sesn:
namespace Seseions {
public class Sesn {
public static bool isNotEmpty() {
return HttpContext.Current.Session.Keys.Count > 0;
}
public struct CreatCurrentSesionVariablsStructNamed {
// some of commonly used variables- still testing options..
public int ManagerCustID;
public int SelectedUercustid;
public int recordID;
public int SelectedMonth;
public int SelectedChosenWorker;
public int SelectedYear ;
public string SelectedTable;
public string SelectedColumn;
public string SqlSelectCommandLastQuery;
public string TableOfUsersReference;
public List<string> Fontlist { get; set; }
}
// converts and extract values of session variables
public class GetValueAS {
public static CreatCurrentSesionVariablsStructNamed ACloneOfTheStructObj(string currntProjectSesVarStructName) {
if(HttpContext.Current.Session[currntProjectSesVarStructName] != null) {
return (CreatCurrentSesionVariablsStructNamed)HttpContext.Current.Session[currntProjectSesVarStructName];
}
public static int _Int(string SesParameterValToReturn) {
return Convert.ToInt32(HttpContext.Current.Session[SesParameterValToReturn]);
}
public static string _String(string SesParameterValToReturn) {
return Convert.ToString(HttpContext.Current.Session[SesParameterValToReturn]);
}
public static DataSet _DataSet(string SesParameterValToReturn) {
return (DataSet)HttpContext.Current.Session[SesParameterValToReturn];
}
public static DataTable _DataTable(string SesParameterValToReturn) {
return (DataTable)HttpContext.Current.Session[SesParameterValToReturn];
}
public static bool _Bool(string SeSnVarToCheckOn) {
if (HttpContext.Current.Session[SeSnVarToCheckOn] == null)
return false;
return (bool)HttpContext.Current.Session[SeSnVarToCheckOn];
}
}
// an easy way to access and mange session variables actions
public enum Act {
Add, Remove, Replace
}
public static void Modify(Act action, string New_SesnVarName= null, object NewP_Value=null, string Currnt_Ses_SesnVarName=null) {
switch (action) {
case Act.Remove:
if (isNotEmpty()) {
HttpContext.Current.Session.Remove(CurSes_ParamName);
}
break;
case Act.Replace:
HttpContext.Current.Session.Remove(CurSes_ParamName);
HttpContext.Current.Session.Add(New_SesnVarName, NewP_Value);
break;
case Act.Add:
HttpContext.Current.Session.Add(NewQs_SesnVarName, NewP_Value);
break;
}
}
}
}
Just don't do this.
critical: do not put Session (user) related data in static variables. It is not thread-safe.
best practice: try to avoid static in ASP.NET for everything else too.
best practice: do not use structs for anything but small, immutable and identity-less types
It seems you are over-engineering this. All you need (for now) is to use some constants for the strings:
public static class SessionKeys
{
public const string ManagerCustID = "ManagerCustID";
...
}
and then you can start focusing on code that adds value to your app.
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";
}
I need advice on structures.
I have 2 sections of code. The first section is as below:
namespace Project.GlobalVariables
{
class IOCard
{
struct InputCard
{
public string CardNo;
public int BaseAddress;
public int LowerAddress;
public int UpperAddress;
public int[] WriteBitNo = new int[16];
public int[] ReadBitNo = new int[16];
}
static InputCard[] InputCards = new InputCard[5];
public static string ACardNo = InputCards[1].CardNo;
public static string BCardNo = InputCards[2].CardNo;
}
}
The second portion is as below:
private void Form1_Load(object sender, EventArgs e)
{
IOCard.ACardNo = "Card A";
IOCard.BCardNo = "Card B";
MessageBox.Show(IOCard.ACardNo);
MessageBox.Show(IOCard.BCardNo);
}
My plan is to be able to assign and retrieve InputCards component by using IOCard as shown in Form1_Load.
However, when I compile the code, I get the following error.
Error 1 'Project.GlobalVariables.IOCard.InputCard.WriteBitNo': cannot have instance field initializers in structs E:\Programming\New platform\StandardPlatform\StandardPlatform\Project\GlobalVariables.cs 16 26 StandardPlatform
Can someone tell me how to solve the error?
Please advise. Thanks.
Here are the classes that I have attempted to create and use, but failed.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Project.GlobalVariables
{
static class IOCard
{
public const int TotalInputCard = 10;
public const int TotalOutputCard = 10;
public class InputCard
{
public string CardNo = "1";
public int BaseAddress;
public int LowerAddress;
public int UpperAddress;
public int[] WriteBitNo = new int[16];
public int[] ReadBitNo = new int[16];
}
public class OutputCard
{
public string CardNo;
public int BaseAddress;
public int LowerAddress;
public int UpperAddress;
public int[] WriteBitNo = new int[16];
public int[] ReadBitNo = new int[16];
}
public static InputCard[] InputCards = new InputCard[TotalInputCard];
public static OutputCard[] OutputCards = new OutputCard[TotalOutputCard];
public static int X100 = InputCards[0].WriteBitNo[0];
public static int Y100 = OutputCards[0].WriteBitNo[0];
}
}
I tried to use these in the Form_Load, like so:
private void Form1_Load(object sender, EventArgs e)
{
IOCard.X100 = 1;
IOCard.Y100 = 1;
}
No matter how much I have tried to search on the net for answers, I have got nowhere.
Please advise. Thanks.
In C#, a struct value is not a reference to an object in the way a value of a class type is. The value of a struct is the "union" of all the values of the instance fields of the struct.
Now, the default value of a struct type is the value where all those fields have their default values. Since the beginning of C#, the syntax:
new S() // S is a value-type
where S is a struct type, has been equivalent to the default value of that struct. There is no constructor call! This is the exact same value which can (nowadays) also be written
default(S) // S is a value-type
Now, things like
struct S
{
int field = 42; // non-static field with initializer, disallowed!
// ...
}
are illegal (cannot have instance field initializers in structs). They could give the impression that the field of a new S() would be 42, but in fact the field of new S() must be the default value of int (which is zero, distinct from 42).
With this explanation, you also see why it is not possible to create a non-static, zero-parameter constructor for a struct type, in C#.
What's it's trying to say is that when you have InputCards = new InputCard[5]; it will allocate a block of memory 5 times the size of an InputCard structure and set all of its bytes to 0. There is no opportunity to execute the int[] WriteBitNo = new int[16]; and such assignments, so you cannot have them.
Your options are to either manually call an initializer for your structs or make it a class and manually initialize the InputCards array with 5 new instances of InputCard.
You will neither be able to initialize a struct's fields nor define a default constructor to initialize it's fields. After looking at your struct, I recommend you use a class instead. It's not recommended to use a struct for a scenario where you have a bunch of fields.
Try this. Initialize the InputCard with a factory function Create():
namespace Project.GlobalVariables
{
class IOCard
{
struct InputCard
{
public string CardNo;
public int BaseAddress;
public int LowerAddress;
public int UpperAddress;
public int[] WriteBitNo;
public int[] ReadBitNo;
static InputCard Create()
{
return new InputCard()
{
CardNo = string.Empty,
WriteBitNo = new int[16],
ReadBitNo = new int[16]
};
}
}
static InputCard[] InputCards = new InputCard[]
{
InputCard.Create(),
InputCard.Create(),
InputCard.Create(),
InputCard.Create(),
InputCard.Create()
};
public static string ACardNo = InputCards[1].CardNo;
public static string BCardNo = InputCards[2].CardNo;
}
}
Use class instead of structure. Structure is used for small types like Point, which are faster to create on the stack and copy, than to create dynamically and pass by reference.
Not sure about the exception, but i have a solution.
You should not use "struct" for this class, it is too much (and storing too much data). If you define it as "class", the same code would work fine.
Is there a particular reason why you want this to be a struct rather than a class?
If you make it a class, it works just fine.
I've got a class like,
public class Revex
{
public IEnumerable<char> AllCharacters = Enumerable.Range(0, 256).Select(Convert.ToChar).Where(c => !char.IsControl(c)).ToArray();
// ...
If I initialize it with
var r = new Revex { AllCharacters = "abcd" };
Will that line above get executed or not (Enumerable.Range...)? If I want it to not get called when I construct my class this way, how would I do that?
I've got about 10 optional character classes like that, so I don't want to write a constructor for every possible combination of them.
This
var r = new Revex { AllCharacters = "abcd" };
Is syntactic sugar for
var r = new Revex();
r.AllCharacters = "abcd";
It should be obvious that the AllCharacters field will be initialized to the default value.
If you don't want the default value you can do this
public class Revex{
public IEnumerable<char> AllCharacters;
public Revex(){
AllCharacters = Enumerable.Range(0, 256).Select(Convert.ToChar).Where(c => !char.IsControl(c)).ToArray()
}
public Revex(IEnumerable<char> allCharacters){
AllCharacters = allCharacters;
}
}
There's one more option which is this:
public class Regex{
private static IEnumerable<char> DefaultAllCharacters(){ return Enumerable.Range.. }
private IEnumerable<char> allCharacters;
public IEnumerable<char> AllCharacters{
get { return allCharacters ?? (allCharacters = DefaultAllCharacters()); }
set { allCharacters = value; }
}
}
Here you lazily initialize the property value if it hasn't already been set. So you don't pay the upfront cost of setting the value if it hasn't been set, but you pay it later once the object is created.
Initialised member variables like this are always initialized prior to execution of the code in your constructor.
In this situation, you have the following sequence
Initialize the AllCharacters member variable
Run the Revex constructor (which might be the compiler supplied default "do nothing" constructor)
Assign a new value to AllCharacters
If you want to avoid this sequence, you'll need to move initialization of AllCharacters into your constructor.
If you also want to allow possible override, you might need something like this:
public class Revex
{
public IEnumerable<char> AllCharacters;
public Revex()
: this( Enumerable.Range(0, 256)
.Select(Convert.ToChar)
.Where(c => !char.IsControl(c))
{
// Nothing
}
public Revex(IEnumerable<char> allCharacters)
{
AllCharacters = allCharacters.ToArray();
}
}
Update 3 Dec
Another alternative would be to use lazy initialization to provide the default values only if explicit values were not provided by the class consumer. You'd need to switch to public properties instead of public fields, and provide logic in the property getters.
public class Revex
{
public IEnumerable<char> AllCharacters
{
get
{
if (mAllCharacters == null)
{
// Default initialization
mAllCharacters
= Enumerable.Range(0, 256)
.Select(Convert.ToChar)
.Where(c => !char.IsControl(c)
}
return mAllCharacters;
}
}
public Revex()
{
// Nothing
}
private IEnumerable<char> mAllCharacters;
}
If you initialise a class variable with it's declaration, the initialisation will happen. So in this case your field will get set twice, once as the class is created and then again when you set the property.
If you want the initialisation to be optional then you need to declare it as:
public IEnunerable<char> AllCharacters;
you will then need to initialise it in your constructor or as you have done by setting the property.