I have a class called RandomGen which generates random variables when called like so:
RandomGen u = new RandomGen();
int QRNOne = u.QuestionRandNo(n);
n++;
How do I then set QRNOne as a global variable to be accessed later? Also, can I do this from within the class, and have it create this variable? (I realise there is no "real" global variable in C# WPF, but you ought to understand what I'm referring to.)
Please read up on static class members.
I'm sure you know that global variables are best avoided if possible, but if you really need a static member variable then you would do something like this:
public class MyClass
{
public static int QRNOne {get; private set;}
public void GenerateRandom(){ ... ; QRNOne = ...; }
}
And then refer to that variable from elsewhere as
public void SomeOtherMethod()
{
int qr = MyClass.QRNone;
...
}
Can you use a static, Singleton style class with properties tor the values you want to use? This should then have global visibilty with sufficient structure and encapsulation.
Related
How do I declare a variable so that every class (*.cs) can access its content, without an instance reference?
In C# you cannot define true global variables (in the sense that they don't belong to any class).
This being said, the simplest approach that I know to mimic this feature consists in using a static class, as follows:
public static class Globals
{
public const Int32 BUFFER_SIZE = 512; // Unmodifiable
public static String FILE_NAME = "Output.txt"; // Modifiable
public static readonly String CODE_PREFIX = "US-"; // Unmodifiable
}
You can then retrieve the defined values anywhere in your code (provided it's part of the same namespace):
String code = Globals.CODE_PREFIX + value.ToString();
In order to deal with different namespaces, you can either:
declare the Globals class without including it into a specific namespace (so that it will be placed in the global application namespace);
insert the proper using directive for retrieving the variables from another namespace.
You can have static members if you want:
public static class MyStaticValues
{
public static bool MyStaticBool {get;set;}
}
First examine if you really need a global variable instead using it blatantly without consideration to your software architecture.
Let's assuming it passes the test. Depending on usage, Globals can be hard to debug with race conditions and many other "bad things", it's best to approach them from an angle where you're prepared to handle such bad things. So,
Wrap all such Global variables into a single static class (for manageability).
Have Properties instead of fields(='variables'). This way you have some mechanisms to address any issues with concurrent writes to Globals in the future.
The basic outline for such a class would be:
public class Globals
{
private static bool _expired;
public static bool Expired
{
get
{
// Reads are usually simple
return _expired;
}
set
{
// You can add logic here for race conditions,
// or other measurements
_expired = value;
}
}
// Perhaps extend this to have Read-Modify-Write static methods
// for data integrity during concurrency? Situational.
}
Usage from other classes (within same namespace)
// Read
bool areWeAlive = Globals.Expired;
// Write
// past deadline
Globals.Expired = true;
A useful feature for this is using static
As others have said, you have to create a class for your globals:
public static class Globals {
public const float PI = 3.14;
}
But you can import it like this in order to no longer write the class name in front of its static properties:
using static Globals;
[...]
Console.WriteLine("Pi is " + PI);
It's been a long while since I have done anything with C# and I decided I wanted to give it a go again. Basically I want to create a class add some variables to it that I can reference outside of the class.
class classname (variablename)
{
function
}
classname (varaiblename = value)
I understand this is probably very much incorrect but that is the gist of wha tI would like to do.
Thank you very much for your time.
You're looking for Properties:
class Foo
{
public int Bar { get; set;}
}
Foo obj = new Foo();
obj.Bar = 5;
I think you need public static variables:
Let's say you've integer variable in class A and you want to control this variable from other classes. There's static variable term which let's you change value of static variables from other classes and it'll affect all of the instance of classes:
Here is my quick code:
public class A {
public static int myValue = 5;
}
So, when you declare your variable like this, you can use and control this variable from other classes such as:
Console.WriteLine(A.myValue); or A.myValue += 5;
How do I declare a variable so that every class (*.cs) can access its content, without an instance reference?
In C# you cannot define true global variables (in the sense that they don't belong to any class).
This being said, the simplest approach that I know to mimic this feature consists in using a static class, as follows:
public static class Globals
{
public const Int32 BUFFER_SIZE = 512; // Unmodifiable
public static String FILE_NAME = "Output.txt"; // Modifiable
public static readonly String CODE_PREFIX = "US-"; // Unmodifiable
}
You can then retrieve the defined values anywhere in your code (provided it's part of the same namespace):
String code = Globals.CODE_PREFIX + value.ToString();
In order to deal with different namespaces, you can either:
declare the Globals class without including it into a specific namespace (so that it will be placed in the global application namespace);
insert the proper using directive for retrieving the variables from another namespace.
You can have static members if you want:
public static class MyStaticValues
{
public static bool MyStaticBool {get;set;}
}
First examine if you really need a global variable instead using it blatantly without consideration to your software architecture.
Let's assuming it passes the test. Depending on usage, Globals can be hard to debug with race conditions and many other "bad things", it's best to approach them from an angle where you're prepared to handle such bad things. So,
Wrap all such Global variables into a single static class (for manageability).
Have Properties instead of fields(='variables'). This way you have some mechanisms to address any issues with concurrent writes to Globals in the future.
The basic outline for such a class would be:
public class Globals
{
private static bool _expired;
public static bool Expired
{
get
{
// Reads are usually simple
return _expired;
}
set
{
// You can add logic here for race conditions,
// or other measurements
_expired = value;
}
}
// Perhaps extend this to have Read-Modify-Write static methods
// for data integrity during concurrency? Situational.
}
Usage from other classes (within same namespace)
// Read
bool areWeAlive = Globals.Expired;
// Write
// past deadline
Globals.Expired = true;
A useful feature for this is using static
As others have said, you have to create a class for your globals:
public static class Globals {
public const float PI = 3.14;
}
But you can import it like this in order to no longer write the class name in front of its static properties:
using static Globals;
[...]
Console.WriteLine("Pi is " + PI);
I have two .cs files (Hex2Bin.cs and Program.cs) and I want to pass the variable end_addr from Program.cs to Hex2Bin.cs
My code in Program.cs:
class Program
{
enum to_exit {
exit_ok = 0,
exit_invalid_args,
exit_to_few_args,
exit_invalid_input_file,
exit_invalid_args_file,
exit_permission_denied,
exit_unexpected_eof
};
// class value holders
static String args_file_name = "";
static String in_u1_name = "";
static String in_u22_name = "";
static String out_name = "";
static short end_addr = 0x0000; // 4-digit Hexadecimal end address
static Byte[] version_code = { 0, 0, 0, 0 }; // 3 bytes version, 1 for extra info
}
Is there anyway I could do this? I know how to do it in c, but I'm very new to c#. Thanks.
C# doesn't work like C with respect to static variables. You can make the variable end_addr available outside the Program class by making it a public field. By default, fields are private.
public static end_addr = 0x0000;
And then it can be accessed like so:
var x = Program.end_addr;
However, I would recommend that you spend a little more time familiarizing yourself with C# idioms and conventions. It seems like your still thinking about C# in terms of C, and they are very different.
if you declare the variable like this:
public static short end_addr = 0x0000;
then from another class you can use it like this:
Program.end_addr
but don't do this, is not object oriented!
if your class Hex2Bin is used/invoked by the Main method of Program class, you should be able to pass your variables as input parameters of the methods you call or set them as properties of the classes/objects you use...
It's enough to mark end_addr as public like so
public static short end_addr = 0x0000;
Then you can access it from anywhere like this
Program.end_addr
It's a better practice though to use properties rather than fields for exposing data.
// Property
public static short end_addr { get; private set; }
// Constructor
public Program()
{
// Initialize property value.
end_addr = 0x0000;
}
You're talking about 'files' but what you really want to do is to pass data from your program's entry point (Program.cs) to a an object of a class (or method of static class) that will process the data, am I right?
If so, this should be pretty simple. You either have to modify your Program.cs and create an instance of the class (the one from Hex2Bin.cs) like this
...
Hex2Bin hex2bin = new Hex2Bin( end_addr );
...
I assume that the Hex2Bin is as follows:
public class Hex2Bin
{
private short endAddress;
public Hex2Bin( short endAddress )
{
this.endAddress = endAddress;
}
}
this will allow you to use the value of end_addr from Program.cs
Another approach is to pass it directly to the method that will make use of it:
Hex2Bin.Method(end_addr);
and in the Hex2Bin file:
public static void Method(short endAddress)
{
//... do the work here
}
Given your background in C, I think you may be mixing runtime with compile time issues.
However, in Hex2Bin.cs, you can create a static method that updates a static variable.
class Hex2Bin
{
static short end_addr = 0x0000;
static void updateEndAddr(short endAddr)
{
end_addr = endAddr;
}
}
I've done some research on global variables, and have come up with the fact that static variables should be able to solve my problem. I don't understand how to make these, though. How would I do so? Also, if static variables would not solve my problem, what should I use?
I want to be able to access a string, bool and int in my main form, from another form. Help?
Static variables (or better yet, properties) would likely work. You would declare this as:
// In Form1 (could be internal or public)
public static bool SomeBool { get; set; }
And then, to access, you'd use Form1.SomeBool = true; or if (Form1.SomeBool) {, etc.
That being said, "global" data like this is discouraged for a reason - there is typically some better way to handle this. For example, you might want to make a custom class that holds your data, and pass a reference to an instance of this class to the new form when you create it.
Not only static, it must be public static. You can simply declare it like any other variable, as in public static int x = 1;. Then you can acces it like ClassFoo.x, but you must be in a static context as well.
If you want this information to be held per form instance (an object) then you don't want to use static fields. On the other hand if what you want is to have some information that you can access from any instance (it is shared) of your class form, or in other words, you want to have this information only once... then yes, use static fields.
What you would want to do is something like this:
//partial because I take you are using a form designer.
//and also because the class is gonna have more things than those showed here.
//in particular the example call a method "UseFields" that I did not define.
public partial class MyForm: form
{
private static bool boolField;
private static string stringField;
private static int intField;
private void Method()
{
//Do something with the fields
UseFields(boolField, stringField, intField);
UseFields(IsBoolFieldSet, SomeString, SharedInformation.SomeInt);
}
//You can also wrap them in a property:
public static bool IsBoolFieldSet
{
get
{
return boolField;
}
//Don't put a set if you want it to be read only
set
{
return boolField;
}
}
//Or declare an static property like so:
public static string SomeString { get; set; }
}
//Another good option is to have this information in a separate class
public class SharedInformation
{
public static int SomeInt { get; set; }
}
Please take care with shared state, in particular in a multithreaded enviroment, because this information may be changed without notice by another object that also has access.