I am making a WinForms application using C#. I would like to declare a variable to access throughout the program but I do not know where to initialize it?
The program is BStree-based and this is what I am trying to initialize:
BSTree<string> record = new BSTree<string>();
If the program is trivial - eg just one form and no additional class files etc (eg a simple school assignment), then you'd probably just declare a static global inside your Form class but outside any methods, eg
public class MyForm : Form
{
static private BSTree<string> record = new BSTree<string>();
public MyForm()
{
...
}
...
}
And then access it from within your MyForm instance(s) as eg MyForm.record.
Note also that you can just declare the variable (eg static private BSTree<string> record;) outside the methods, but then initialise it (to eg new BSTree<string>()) from within eg your constructor. There's a very subtle difference between the two approaches (ie effects the order in which various members are initialised), but this is rarely of consequence.
Be aware that the static member "belongs" to the class, and so there's only one "version" of that member. ie there's not a separate "version" of that member for each instance of your class.
But otherwise, you might have a static "configuration" or "globals" class, that contains these values (and perhaps other values read from eg a config file):
public static class MyConfig
{
static public BSTree<string> record = new BSTree<string>();
...
}
and then you'd access this from within your MyForm class like MyConfig.record.
Although - ideally you should expose properties not fields, eg:
public static class MyConfig
{
static private BSTree<string> record = new BSTree<string>();
static public BSTree<string> Record
{
get {return record;}
set {record = value;}
}
...
}
and then you'd access this from within your MyForm class like MyConfig.Record. This would give direct access to the underlying record member.
But a more robust approach would be to create specific methods that operate on the members on behalf of the consumer, rather than just exposing the members directly to the consumer. That way you can limit the types of operations that are allowed on them, and can expose the results in a specific way etc. ie you're adding value to the underlying members, rather than just "holding" them.
public static class MyStaticBStreeInstance
{
public static BSTree Instance {get;private set;}
static MyStaticBStreeInstance()
{
Instance = new BSTree<string>();
}
}
and from anywhere , you can access it by using below code
var bstree = MyStaticBStreeInstance.Instance
Related
Am new to C#, but have a plenty of experience of VB.net, now my issue is that there are no modules in C# and i need to define a class which is accessible in all classes and i don't know how to do it.
For example I have a "classProject" and I need to make it accessible everywhere, so in vb.net , I will define it in module like below.
Module ModuleMain
Public tProject As New ClassProject
End Module
Now, I need to do same in C#.
Thanks in advance.
You can do this in your case:
namespace MyProject
{
public static class classProject
{
int myIntvar = 0;
string myStringvar = "test";
}
}
And you can use this static class in your other classes like:
public class Test
{
int intTest = classProject.myIntvar; //will be 0
string stringTest = classProject.myStringvar; // will be test
}
You can use the variables in the static class since a static variable shares the value of it among all instances of the class. When you create multiple instances of classProject class, the variables myIntvar and myStringvar are shared across all of other classes in your project. Thus, at any given point of time, there will be only one integer and one string value contained in the respective variable's.
It sounds like you're looking for a static class. You can reference the access modifiers here: https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/access-modifiers
I think you need to extends your other classes to class father (ClassProject) And you can access to it with youur children classes.
//[access modifier] - [class] - [identifier]
public class Customer
{
// Fields, properties, methods and events go here...
}
see more
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 searched about static variables in C#, but I am still not getting what its use is. Also, if I try to declare the variable inside the method it will not give me the permission to do this. Why?
I have seen some examples about the static variables. I've seen that we don't need to create an instance of the class to access the variable, but that is not enough to understand what its use is and when to use it.
Second thing
class Book
{
public static int myInt = 0;
}
public class Exercise
{
static void Main()
{
Book book = new Book();
Console.WriteLine(book.myInt); // Shows error. Why does it show me error?
// Can't I access the static variable
// by making the instance of a class?
Console.ReadKey();
}
}
A static variable shares the value of it among all instances of the class.
Example without declaring it static:
public class Variable
{
public int i = 5;
public void test()
{
i = i + 5;
Console.WriteLine(i);
}
}
public class Exercise
{
static void Main()
{
Variable var1 = new Variable();
var1.test();
Variable var2 = new Variable();
var2.test();
Console.ReadKey();
}
}
Explanation: If you look at the above example, I just declare the int variable. When I run this code the output will be 10 and 10. Its simple.
Now let's look at the static variable here; I am declaring the variable as a static.
Example with static variable:
public class Variable
{
public static int i = 5;
public void test()
{
i = i + 5;
Console.WriteLine(i);
}
}
public class Exercise
{
static void Main()
{
Variable var1 = new Variable();
var1.test();
Variable var2 = new Variable();
var2.test();
Console.ReadKey();
}
}
Now when I run above code, the output will be 10 and 15. So the static variable value is shared among all instances of that class.
C# doesn't support static local variables (that is, variables that are declared in method scope).
https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/static-classes-and-static-class-members#static-members
You can declare static fields (class members) though.
Reasoning: Static field is a state, shared with all instances of particular type. Hence, the scope of the static field is entire type. That's why you can't declare static instance variable (within a method) - method is a scope itself, and items declared in a method must be inaccessible over the method's border.
static variables are used when only one copy of the variable is required. so if you declare variable inside the method there is no use of such variable it's become local to function only..
example of static is
class myclass
{
public static int a = 0;
}
Variables declared static are commonly shared across all instances of a class.
Variables declared static are commonly shared across all instances of a class. When you create multiple instances of VariableTest class This variable permanent is shared across all of them. Thus, at any given point of time, there will be only one string value contained in the permanent variable.
Since there is only one copy of the variable available for all instances, the code this.permament will result in compilation errors because it can be recalled that this.variablename refers to the instance variable name. Thus, static variables are to be accessed directly, as indicated in the code.
Some "real world" examples for static variables:
building a class where you can reach hardcoded values for your application. Similar to an enumeration, but with more flexibility on the datatype.
public static class Enemies
{
public readonly static Guid Orc = new Guid("{937C145C-D432-4DE2-A08D-6AC6E7F2732C}");
}
The widely known singleton, this allows to control to have exactly one instance of a class. This is very useful if you want access to it in your whole application, but not pass it to every class just to allow this class to use it.
public sealed class TextureManager
{
private TextureManager() {}
public string LoadTexture(string aPath);
private static TextureManager sInstance = new TextureManager();
public static TextureManager Instance
{
get { return sInstance; }
}
}
and this is how you would call the texturemanager
TextureManager.Instance.LoadTexture("myImage.png");
About your last question:
You are refering to compiler error CS0176. I tried to find more infor about that, but could only find what the msdn had to say about it:
A static method, field, property, or event is callable on a class even
when no instance of the class has been created. If any instances of
the class are created, they cannot be used to access the static
member. Only one copy of static fields and events exists, and static
methods and properties can only access static fields and static
events.
Static variables are used when only one copy of it is required. Let me explain this with an example:
class circle
{
public float _PI =3.14F;
public int Radius;
public funtionArea(int radius)
{
return this.radius * this._PI
}
}
class program
{
public static void main()
{
Circle c1 = new Cirle();
float area1 = c1.functionRaduis(5);
Circle c2 = new Cirle();
float area2 = c1.functionRaduis(6);
}
}
Now here we have created 2 instances for our class circle , i.e 2 sets of copies of _PI along with other variables are created. So say if we have lots of instances of this class multiple copies of _PI will be created occupying memory. So in such cases it is better to make such variables like _PI static and operate on them.
class circle
{
static float _PI =3.14F;
public int Radius;
public funtionArea(int radius)
{
return this.radius * Circle._PI
}
}
class program
{
public static void main()
{
Circle c1 = new Cirle();
float area1 = c1.functionRaduis(5);
Circle c2 = new Cirle();
float area2 = c1.functionRaduis(6);
}
}
Now no matter how many instances are made for the class circle , only one copy exists of variable _PI saving our memory.
Static classes don't require you to create an object of that class/instantiate them, you can prefix the C# keyword static in front of the class name, to make it static.
Remember: we're not instantiating the Console class, String class, Array Class.
class Book
{
public static int myInt = 0;
}
public class Exercise
{
static void Main()
{
Book book = new Book();
//Use the class name directly to call the property myInt,
//don't use the object to access the value of property myInt
Console.WriteLine(Book.myInt);
Console.ReadKey();
}
}
The data members and function members that operate on the instance of the type
are called instance members. The int’s ToString method (for example) are examples of instance members. By default, members are instance members.
Data members and function members that don’t operate on the instance of the type, but rather on the type itself, must be marked as static. The Test.Main and Console.WriteLine methods are static methods. The Console class is actually a static class, which means all its members are static. You never actually create instances of a Console—one console is shared across the whole application.
In response to the "when to use it?" question:
I often use a static (class) variable to assign a unique instance ID to every instance of a class. I use the same code in every class, it is very simple:
//Instance ID ----------------------------------------
// Class variable holding the last assigned IID
private static int xID = 0;
// Lock to make threadsafe (can omit if single-threaded)
private static object xIDLock = new object();
// Private class method to return the next unique IID
// - accessible only to instances of the class
private static int NextIID()
{
lock (xIDLock) { return ++xID; }
}
// Public class method to report the last IID used
// (i.e. the number of instances created)
public static int LastIID() { return xID; }
// Instance readonly property containing the unique instance ID
public readonly int IID = NextIID();
//-----------------------------------------------------
This illustrates a couple of points about static variables and methods:
Static variables and methods are associated with the class, not any specific instance of the class.
A static method can be called in the constructor of an instance - in this case, the static method NextIID is used to initialize the readonly property IID, which is the unique ID for this instance.
I find this useful because I develop applications in which swarms of objects are used and it is good to be able to track how many have been created, and to track/query individual instances.
I also use class variables to track things like totals and averages of properties of the instances which can be reported in real time. I think the class is a good place to keep summary information about all the instances of the class.
Try calling it directly with class name Book.myInt
On comparison with session variables, static variables will have same value for all users considering i am using an application that is deployed in server. If two users accessing the same page of an application then the static variable will hold the latest value and the same value will be supplied to both the users unlike session variables that is different for each user. So, if you want something common and same for all users including the values that are supposed to be used along the application code then only use static.
You don't need to instantiate an object, because yau are going to use
a static variable:
Console.WriteLine(Book.myInt);
Static variable retains it's previous value until the program exit. Static is used by calling directly class_Name.Method() or class_Name.Property. No object reference is needed. The most popular use of static is C#'s Math class.
Math.Sin(), Math.Cos(), Math.Sqrt().
I'm pretty new to C# and I was trying out a few things. I have a label (named 'newLabel') in the form1.cs. I have a class named 'methods.cs'. In this class I have the method
public static void updateLabel()
what I want to do is:
public static void updateLabel()
{
newLabel.Text = "New Value";
}
but this doesn't work, probably because the method is in methods.cs and the newLabel is in form1.cs.
I had the same problem with declared variables. In the methods.cs I had the variable
int value;
but I couldn't use this variable in form1.cs. I fixed this by doing
public static int value { get; set; }
I have no idea what that did but it works, but I don't know how I can apply this trick with the label.
Could someone help me with this?
Thanks!
You should read up about OOP and encapsulation. Basically you want the form
to access private fields in another object (your class) - this is restricted by encapsulation, that's why you are running into problem - you can get around them by adding those fields and methods to the "public" interface that your class is declaring by making them public properties and methods, i.e in your example:
public int Value {get;set;}
Sometimes composition is used, i.e. in your example since your class is directly accessing the form you could have a form property on your class:
public Form ViewForm {get;set;}
It would be best if you learnt C# from tutorials, but the answer to this particular question lies with something called "scope"
Essentially, scope is the visibility of variables, classes, functions and objects. A variable marked "private" can only be seen within the thing that created it (if it's created inside a function it will always be private and any variables defined inside a function can only be used inside that function). If it's created inside a class only that class can use it.
Variables or functions denoted as public (this can only be done inside a class) can be seen from outside that class. To do that you would invoke myClass.myVariable to access the variable or myClass.myFunction() to access the function.
To denote the visibility of an object you use the keywords "public" or "private". Note: This only applies to variables and functions inside classes (it also applies to other things within classes, such as nested classes and structs, but that's outside the scope of this basic intro).
for example:
class myClass
{
private int myInt;
public void myfunction()
{
myInt = 1;
}
}
This will work, as myInt can be seen by anything inside myClass
class myOtherClass
{
private void myfunction()
{
myClass myObject = new myClass();
myObject.myInt = 2;
}
}
This will not, as myInt is private to myObject and only myObject can change it. myOtherClass does not have permission and it cannot see it.
class myOtherClassTwo
{
private void myfunction()
{
myClass myObject = new myClass();
myObject.myFunction();
}
}
This, thankfully, will work. myFunction was set as public in the myClass class, so it can be seen by anybody outside of the class.
Now the keyword static which you use has a whole different meaning. I advise you not to use it until you've learned about it as you're only adding additional complexity to your problems.
I hope this has cleared things up, though I must urge you to follow some real tutorials as these basics must be thoroughly detailed or you'll be caught out later on.
Since your updateLabel method accesses the label inside the form, correct object-oriented design would dictate that this method should be in the form, too. Then you have no problem accessing newLabel.
Technically speaking: newLabel doesn’t mean anything outside a form object. You could have several copies of your form, which would mean several copies of your newLabel; which of them should it refer to? Of course the computer won’t take a guess there; it’ll expect that you tell it which form you want to use.
The reason you couldn’t access the value variable is because it was private. If you had changed it simply to:
public static int value;
then it would have worked.
From the Form1, call the updateLabel method in the mothods class:
methods updateMethod = new methods();
newLabel.Text = updateMethod.updateLabel();
With this method in the methods class:
public static string updateLabel(){
return "New Value";
}
In almost all of my classes, I have a mixture of properties and internal class variables. I have always chosen one or the other by the rule "property if you need it externally, class variable if not". But there are many other issues which make me rethink this often, e.g.:
at some point I want to use an internal variable from outside the class, so I have to refactor it into a property which makes me wonder why I don't just make all my internal variables properties in case I have to access them externally anyway, since most classes are internal classes anyway it aren't exposed on an API so it doesn't really matter if the internal variables are accessible from outside the class or not
but then since C# doesn't allow you to instantiate e.g. List<string> property in the definition, then these properties have to be initialized in every possible constructor, so these variables I would rather have internal variables just to keep things cleaner in that they are all initialized in one place
C# code reads more cleanly if constructor/method parameters are camel case and you assign them to pascal case properties instead of the ambiguity of seeing templateIdCode and having to look around to see if it is a local variable, method parameter or internal class variable, e.g. it is easier when you see TemplateIdCode = templateIdCode that this is a parameter being assigned to a class property. This would be an argument for always using only properties on internal classes.
e.g.:
public class TextFile
{
private string templateIdCode;
private string absoluteTemplatePathAndFileName;
private string absoluteOutputDirectory;
private List<string> listItems = new List<string>();
public string Content { get; set; }
public List<string> ReportItems { get; set; }
public TextFile(string templateIdCode)
{
this.templateIdCode = templateIdCode;
ReportItems = new List<string>();
Initialize();
}
...
When creating internal (non-API) classes, what are your strategies in deciding if you should create an internal class variable or a property?
If I have a private variable that I find needs public access at a later point, I just create a property that uses it as it's private member, ex:
private List<string> listItems = new List<string>();
Public List<string> ListItems
{
get{return listItems;}
set{listItems = value;}
}
This allows you to create public access to the data, without having to refactor any code. It also allows you to initialize the data in the private member, and not have to do it in the constructor.
One more advantage is that any modifications to the data that you want to perform for anyone accessing the public property, can be done in the property's getter.
Even though VS2008 introduced Automatic Properties as a feature, I still prefer the VS2005 style of properties.