I'm trying to make a program in Visual C# that has my one created class, and at application launch it creates an array of my class object, and this array of my object can be used all over the program. So any function, or a control's event can access the array of objects and their member variables.
I created my class as "public" but for some reason i get these errors upon build:
"The name 'MyArrayObjectNameHere' does not exist in the current context"
When I try to access the objects member variables inside a load file dialog event in which I am trying to load data from a file into the member variables of the object array.
Is there a certain place the object array needs to be declared and constructed so it exists in every context? If so, can you tell me where this is?
I currently declare it in the main function before form1 is run.
My class definition looks like this in its own .cs file and the programs namespace:
public class MyClass
{
public int MyInt1;
public int MyInt2;
}
I declare the array of objects like this inside the main function before the form load:
MyClass[] MyArrayObject;
MyArrayObject = new MyClass[50];
for (int i = 0; i < 50; i++)
{
MyArrayObject[i] = new MyClass();
}
Thanks in advance for any help.
Your problem is that you are defining it within the main function, hence it will only exist inside the main function. you need to define it inside the class, not inside the function
public partial class Form1:Form
{
MyClass[] MyArrayObject; // declare it here and it will be available everywhere
public Form1()
{
//instantiate it here
MyArrayObject = new MyClass[50];
for (int i = 0; i
Only static objects are available in all contexts. While your design lacks... er, just lacks in general, the way you could do this is to add a second, static class that maintains the array of your MyClass:
public static class MyClassManager
{
private MyClass[] _myclasses;
public MyClass[] MyClassArray
{
get
{
if(_myclasses == null)
{
_myClasses = new MyClass[50];
for(int i = 0; i < 50;i++)
_myClasses[i] = new MyClass();
}
return _myclasses;
}
}
}
Do yourself a fav and grab CLR Via C# by Jeffrey Richter. Skip the first couple chapters and read the rest.
You need to make the array a static member of some class, .NET does not have a global scope outside of any class.
e.g.
class A
{
public static B[] MyArray;
};
You can then access it anywhere as A.MyArray
That't good.It is very useful for learners like me.
Related
I'm making c# app where I need to access method in partial class from another class.
To be more specific I want to add items to listview from class that is different from partial class but in same namespace.
I tried like this:
public partial class Aa : Form
{
public static void UpdateListView(string[] array)
{
if (ProcessNetUsageList.InvokeRequired)
{
ProcessNetUsageList.Invoke(new Action<string[]>(UpdateListView), array);
}
else
{
ListViewItem item = new ListViewItem(array[0]);
for (int i = 1; i < 4; i++)
item.SubItems.Add(array[i]);
ProcessNetUsageList.Items.Add(item);
}
}
}
and then access it from another class like:
class Test
{
test()
{
ProgramName.Aa.UpdateListView(someArray);
}
}
But its giving an error because static method can only access static variables,and my listview isnt static(i created that listview in vs designer).
If i remove static keyword from method in partial class then i cant access it.I tried to create instance of partial class but without success.Any idea is welcome
note:Im using Invoke in my UpdateListView method because later that will be running on new thread
The nature of an object-oriented language is that objects don't have universal access to modify other objects. This is a good thing.
You've provided relatively little code so it's hard to provide a perfect answer here, but there are a few paradigms that resolve this issue.
One is to pass the instance to your test class, like this:
class Test
{
test(ProgramName.Aa form)
{
form.UpdateListView(someArray);
}
}
Or, if class test actually contains the ListView, you can pass that to a static method in Aa.
class Test
{
ListView someListView;
test()
{
ProgramName.Aa.UpdateListView(someListView, someArray);
}
}
Ultimately, you should think about the logical relationship between these objects to determine how these objects should communicate.
Remove the static keyword from UpdateListView, as you have done before. In test(), you need to instantiate Aa before you access UpdateListView.
Aa temp = new Aa()
You can then access the method by using
temp.UpdateListView(someArray);
public partial class FormRestaurant : Form
public Tables[] AllTables = new Tables[4];
I create an array of type Tables which is a class that I made. If I try to reference this from a third class (Parties.cs) by doing:
public void AssignTable()
{
for (int i = 0; i < **FormRestaurant.AllTables**.Length; i++)
{
if (**FormRestaurant.AllTables[i]**.TableCapacity <= PartySize)
{
}
}
}
I am told that I need an object reference. How exactly do I do this?
I tried making the array static but it didn't seem to work. Also I get this error when I try to make the AllTables array public.
Error 1 Inconsistent accessibility: field type
'Restaurant_Spil.Tables[]' is less accessible than field
'Restaurant_Spil.FormRestaurant.AllTables'
When it says you need an object reference, it's trying to tell you that it needs an instance of your class. Say you have your class:
public partial class FormRestaurant : Form
{
public Tables[] AllTables = new Tables[4];
}
If you want to get the length of the Tables[] array in Parties.cs, then Parties needs an instance of FormRestaurant; it makes no sense to ask for the length of FormRestaurant.AllTables. Instead you should:
public class Parties
{
int length;
FormRestaurant f;
public Parties()
{
f = new FormRestaurant();
length = f.AllTables.Length;
}
}
the f variable is the object reference that was mentioned in your first error.
All you need to do is put your Tables class public.
You cannot expose private field type in a public class
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().
Updated to reflect to my own source
I'm in process of building my first winform application in c# and I'm trying to figure out the best practice for structuring my classes to work smoothly when I use them in my forms.
I have a couple of examples which I will try to explain the best way i can.
When working with get/set variables in a class, the best practice should be something like this:
JobMove.cs
public class JobMove
{
private List<string> jobNames { get; set; }
public string Scanner;
public JobMove()
{
this.Scanner = Properties.Settings.Default.Scanner;
}
public void ListSelected(ListBox lbx)
{
foreach (string jName in this.jobNames)
{
lbx.Items.Add(jName);
}
}
public static List<string> GetCheckedJobs(ListView lw)
{
int countChecked = lw.CheckedItems.Count;
int itemCount = 0;
List<string> jList = new List<string>();
foreach (ListViewItem item in lw.CheckedItems)
{
JobInfo jobInfo = Job.Find(Convert.ToInt32(lw.Items[item.Index].SubItems[1].Text));
jList.Add(jobInfo.Name);
itemCount++;
}
return jList;
}
}
My problem is when I combine this with my forms and I call this, then I would try to do something like this:
MyForm1.cs
public partial class MyForm1 : Form
{
private void btnMoveJobs_Click(object sender, EventArgs e)
{
Properties.Settings.Default.Scanner = cbxScanners.SelectedItem.ToString();
JobMove moveJobs = new JobMove();
frmMoveJobs FrmMoveJobs = new frmMoveJobs();
FrmMoveJobs.ShowDialog();
}
}
MyForm2.cs
public partial class frmMoveJobs : Form
{
public frmMoveJobs()
{
InitializeComponent();
JobMove moveJobs = new JobMove();
lblFrom.Text = moveJobs.Scanner;
moveJobs.ListSelected(lbxJobsToMove);
cbxMjScanners.DataSource = System.Enum.GetValues(typeof(Scanners));
}
}
But when I call MyClass in MyForm2 and I want to call the DoSomethingElse method, then myString will be reset to a null value. And that makes sense to me, but how do I work around this?
I tried to figure out what to use here to get easier around these flaws in my code, but my knowledge is far too weak to just implement an easy solution.
I know I could just store this variable in Settings.settings as an example, but to me that just seems like a real overload for such a simple task.
I might just need a point in the right direction to right on what to do in this situation.
If you do a MyClass myClass = new MyClass(); then indeed - the values are independent and unrelated. If you want to share the MyClass instance then pass the MyClass instance between the forms. Perhaps:
using(var form2 = new Form2()) {
form2.SensibleName = existingMyClassInstance;
form2.ShowDialog();
}
(note the using above btw; when using ShowDialog() it is your job to make sure the form is disposed; it only gets disposed automatically if using Show())
Firstly, they're properties, not variables (the variables are the underlying data source).
Secondly, the whole point of get/set accessors is so you can get and set the value without needing helper methods.
Thirdly, and as to your problem, you're creating a new instance of the class in each form (hinted at by the new keyword) and the value of the property will be whatever it is initialised as on construction of the instance (or not.) i.e. the values of properties are not shared between different instances of the same type.
Think of the mold for a key: I can get multiple instances of the key cut from a "blueprint", but any damage that one suffers won't be reflected by the rest - they're unique in that sense.
If you want the forms to both access the same instance of that type, then you will need to stash the instance somewhere in your code which is accessible to both.
A few options:
Pass in an instance of MyClass in the form2's constructor.
Make MyClass a static property of either Form1 or Form2 and access it via that on the other form.
Make MyClass static (not recommended).
If you want to use the instance of MyClass created in MyForm1 inside of MyForm2, you need to provide it to MyForm2.
Something like this would work:
public partial class MyForm2 : Form
{
public MyForm2(MyClass given)
{
InitializeComponent();
given.DoSomethingElse();
}
}
Easy Solution:
private static string myString { get; set; }
Why: because you initialize the class again when initializing Form2 and it will create a new class. With the "static" keyword you create a property which is the same in all instances of this class.
BUT: please read some books before continuing, this would be the solution to this problem, but the source of many others. Try to understand C# and Forms first, than (or alongside with reading/learning) start coding!
this is because each of your form has a new object of "MyClass".
To achieve what you want to do use a static property... this won't be initialized and gives back the same value for each object of MyClass
it looks like this
public class MyClass {
public static string myString { get; set; }
public void ChangeMyString(string newString)
{
myString = newString;
}
public void DoSomethingElse()
{
MessageBox.Show(myString);
}
}
I'm working with a class library in C# with its own methods and I want to create an array from this library, but I when call it in the main program I cant see its methods.
public class ClassLibrary1
{
public int num;
public ClassLibrary1 ()
{
}
public void Readdata()
{
Console.Write("write a number ");
num = int.Parse(Console.ReadLine());
}
}
program.cs :
ClassLibrary1[] arraynumbers = new ClassLibrary1[5];
arraynumbers.Readdata();
And I can't use Readdata().
Can anyone help me?
If you want to call methods in your class, you'll have to create at least one instance. As it is, all you've done is create an array of null references, and then attempt to call your method on the array. Here's one way you could do it.
ClassLibrary1[] arraynumbers = new ClassLibrary1[5];
for(int i = 0; i < 5; i++)
{
arraynumbers[i] = new ClassLibrary1();
}
arraynumbers[0].Readdata();
You can't use Readdata the way you've put it because ClassLibrary1[] is an ARRAY object, not a ClassLibrary1 object, in which your method is defined.
You'd have to do something like this instead:
arraynumbers[0].Readdata();
Readdata() is a method of the ClassLibrary1 instance, not the array that holds ClassLibrary1 instances.
Methods that are defined on a class may not be called on a collection of that class. If you want to use a method on a collection, consider making an extension method:
public static class ClassLibrary1Extensions
{
public static Readdata(this ClassLibrary[] value)
{
...
}
}
The "this" keyword in the first parameter allows you to "pretend" this method is on a type of "ClassLibrary1[]" or array. I.e. extending that type.