How to make an array of objects visible to other functions - c#

In my current program I am building an array of objects and then populating it, however I need to then access this populated array from another function within the same class. In C I would do this by making the array global, but global variables dont exist in C# and when I try to use the "Static" parameter it says arrays cant be static.
namespace FormsTest1
{
public partial class Form1 : Form
{
public int AppCount;
public static applications[] appList;
public Form1() //Main Entry point of program
{
IEnumerable<int> apps = VolumeMixer.EnumerateApplications();
AppCount = apps.Count();
int i = 0;
applications[] appList = new applications[AppCount];
foreach (int app in apps)
{
appList[i] = new applications();
appList[i].setProcessID(app);
appList[i].populate();
i++;
}
for (int j = 0; j < AppCount; j++) { ChannelSelect1.Items.Add(appList[j].Name); }
}
private void ChannelSelect1_SelectedIndexChanged(object sender, EventArgs e)
{
for (int k = 0; k < AppCount; k++)
{
if (ChannelSelect1.Text == appList[k].Name) //<-- This array is not the one I populate in Form1()
{ Channels[0] = appList[k].PID; }
}
}
public class applications
{
public int PID;
public string ProcessName;
public string WindowName;
public string Name;
public string Path;
public void setProcessID(int ID) { PID = ID; }
public string getProcessName() { return ProcessName; }
public string getWindowName() { return WindowName; }
public string getName() { return Name; }
public string getPath() { return Path; }
public void populate()
{
//stuff
}
}
}
I cant pass the array into the other functions cause they are event driven, and I need the index-ability of arrays.
How do I declare and populate an array of objects in one function, and then use that array in another function in the same class?

Change your constructor from
applications[] appList = new applications[AppCount];
to
appList = new applications[AppCount];
You should initialize your instance field instead of creating a new local one.
Btw: It is not necessary to make the array static.

Related

C# assigning a class array but value is treated as 0

i'm currently stuck on a project. I have to instantiate a class x amount of times. The value of x can be different every time you run the program. Here is my code for clarification.
public partial class Form1 : Form
{
private static int Rooms;
private Room[] room = new Room[Rooms];
public Form1()
{
InitializeComponent();
Start();
}
private void Start()
{
string[] lines = File.ReadAllLines(#"C:Path\Test.txt");
Rooms = lines.Length;
for (int i = 0; i < room.Length; i++)
{
if (i == 13)
{
continue;
}
else
{
this.room[i] = new Room(i);
}
listBox1.Items.Add(this.room[i].RoomNumber.ToString());
}
}
}
While debugging, hovering over Rooms at Private static int Rooms; displays the correct value; Hovering over Rooms at private Room[] room = new Room[Rooms]; also displays the correct value, but treats it as if its 0. It doesnt add the room numbers to the listbox. If i use Rooms + 1, it just adds 1 roomnumber. Though if i replace Rooms with the correct x value, it does work.
Does anyone here know what happens and how to fix this?
Your static variables initialize before the constructor is called (specifically, they are initialized as soon as the class is referenced by code). By default, int variables are initialized to zero, which is why the array has zero elements at first, but shows as the correct value in the debugger. You need to move your array initialization after you assign the Rooms variable:
public partial class Form1 : Form
{
private static int Rooms;
private Room[] room;
public Form1()
{
InitializeComponent();
Start();
}
private void Start()
{
string[] lines = File.ReadAllLines(#"C:Path\Test.txt");
Rooms = lines.Length;
room = new Room[Rooms];
for (int i = 0; i < room.Length; i++)
{
if (i == 13)
{
continue;
}
else
{
this.room[i] = new Room(i);
}
listBox1.Items.Add(this.room[i].RoomNumber.ToString());
}
}
}

static LIST of class returning same value

I have two classes, one contains the value I want to maintain and it is declared as [serializable] since I may want to store the results in a file later.
namespace WindowsFormsApp1
{
[Serializable]
public class Class1
{
string Something = "";
public Class1(string something)
{
Something = something;
}
public Class1()
{
Something = "";
}
public string something
{
get { return Something; }
set { Something = value; }
}
}
}
The second declares a List of this class along with a few access functions
namespace WindowsFormsApp1
{
class Class2
{
public static List<Class1> aClass = new List<Class1>();
public static int cnt = 0;
public void AddStaticString(Class1 aString)
{
aClass.Add(aString);
cnt++;
}
public string GetAllStrings()
{
string aFullString = "";
int cnt = 0;
while (cnt < aClass.Count)
{
aFullString = aClass[cnt].something;
cnt++;
}
return aFullString;
}
}
}
Now a simple bit of code to add to the LIST and try to extract it
namespace WindowsFormsApp1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Class1 aClass = new Class1();
Class2 aSClass = new Class2();
aClass.something = "AAAAA";
aSClass.AddStaticString(aClass);
aClass.something = "BBBBB";
aSClass.AddStaticString(aClass);
aClass.something = "CCCCC";
aSClass.AddStaticString(aClass);
richTextBox1.Text = aSClass.GetAllStrings();
}
}
}
The richTextBox always displays the last item only (CCCCC), even though I can see the proper values being input into the LIST.
Can I not access the members of the LIST with aFullString = aClass[cnt].something; ?
You are just returning the last string from the list in GetAllStrings. Rather you could append it to existing item, or maybe separate them using comma, whatever you want.
For example, you can append those values using simply:
aFullString += aClass[cnt].something + ",";
But that would leave a comma at the end of the string.
Rather, if you need comma separated values, you could just join the strings using LINQ,
public string GetAllStrings()
{
return string.Join(",", aClass.Select(item => item.something));
}
Also, in button1_Click you are adding the same instance of Class1 to the list in Class2. If you need separate instances of the class, you should create new instance before calling AddStaticString:
private void button1_Click(object sender, EventArgs e)
{
Class2 aSClass = new Class2();
Class1 aClass = new Class1();
aClass.something = "AAAAA";
aSClass.AddStaticString(aClass);
aClass = new Class1();
aClass.something = "BBBBB";
aSClass.AddStaticString(aClass);
aClass = new Class1();
aClass.something = "CCCCC";
aSClass.AddStaticString(aClass);
richTextBox1.Text = aSClass.GetAllStrings();
}
You should, but the way you are assigning that aFullString variable will always show the last value of the list.
You should try it like this:
public string GetAllStrings()
{
string aFullString = "";
int cnt = 0;
while (cnt < aClass.Count)
{ //+ to keep the previous values too
aFullString += aClass[cnt].something;
cnt++;
}
return aFullString;
}
In this method:
public string GetAllStrings()
{
string aFullString = "";
int cnt = 0;
while (cnt < aClass.Count)
{
aFullString = aClass[cnt].something;
cnt++;
}
return aFullString;
}
You set aFullString to the last collection item's something.
What you want is probably string concatenation. You don't need while loop - for or foreach loop suit better, or even string.Join would be the best option:
public string GetAllStrings()
{
return String.Join(" ", aClass.Select(x => x.something);
}
Please, note that your code has many style and naming errors, unused or useless variables like class members Something and cnt, and doesn't make much sense in general.
You need to follow C# naming conventions and rules to make your code readable and understandable by other developers.

How can I populate a string array with a parameter method C#

I am trying to populate a string array called "items" with a pre written method called "insert".
The project has pre written code "b.insert("apple");" etc etc and the method given is "public void insert(T item)". I have to write the code in this method to make the "insert" function work. I have to pass "item" into "items" array but my for loop simply gives me the output "milk" 10 times. Because of this, I know that "item" value is simply changing to the last string passed in the insert method. Would I have to write a nested for loop where "item" is a counter? In this case "item" cannot be a counter because it is a string type. Should I convert "item" into an array?
I'm not sure why such a seemingly simple task has me stumped by I've been at it for hours and at this point I just want to sort it out for the sake of sanity.
thanks in advance
class Program
{
static void Main(string[] args)
{
BoundedBag<string> b = new BoundedBag<string>("ShoppingList", 10);
b.insert("apple");
b.insert("eggs");
b.insert("milk");
Console.WriteLine(b);
Console.ReadKey();
}
}
public interface Bag<T> where T : class
{
void insert(T item);
string getName();
bool isEmpty();
}
public class BoundedBag<T> : Bag<T> where T : class
{
private string bagName; // the name of the bag
protected int size; // max size of the bag
private int lastIndex;
protected T[] items;
public BoundedBag(string name, int size)
{
bagName = name;
this.size = size;
rnd = new Random();
items = new T[size];
}
public string getName()
{
return bagName;
}
public bool isEmpty()
{
return lastIndex == -1;
}
public bool isFull()
{
if(items.Length >= size)
{
return true;
}
else { return false;}
}
public void insert(T item)
{
// fill in the code as directed below:
// insert item into items container
// throws FullBagException if necessary
for (int i = 0; i < size; i++)
{
items[i] = item;
}
}
}
You only want to insert one item into your array on insert so you shouldn't have a loop at all. Use the lastIndex field to insert one item into the appropriate place in the array:
public void insert(T item)
{
// fill in the code as directed below:
// insert item into items container
// throws FullBagException if necessary
if(isFull())
{
throw new FullBagException();
}
items[++lastIndex] = item;
}
Unfortunately your isFull method is also broken and your isEmpty method won't work properly unless you change the constructor.
public BoundedBag(string name, int size)
{
bagName = name;
this.size = size;
items = new T[size];
lastIndex = -1;
}
public bool isFull()
{
return lastIndex == size - 1;
}

Not able to make the value types inside a structure as mutable in c#

I am converting VB6 codes to C# Here I have to convert array of struct into List approach in c# but not able to modify the value in the below sample code getting error as
"Cannot modify the return value of System.Collections.Generic.List<test.Program.TagFieldValue>.this[int]because it is not a variable".
What am I doing wrong.. Is there any other way to do it without converting my type to class?
using System;
using System.Collections.Generic;
namespace test
{
class Program
{
private struct TagFieldValue
{
private int _ID;
public int ID { get { return _ID; } set { _ID = value; } }
}
private List<TagFieldValue> mFieldValues = new List<TagFieldValue>();
static void Main(string[] args)
{
Program obj = new Program();
obj.test();
}
public void test()
{
for (int i = 1; i <= 10; i++)
{
TagFieldValue temp = new TagFieldValue();
temp.ID = i;
mFieldValues.Add(temp);
}
for (int i = 0; i <= 9; i++)
{
mFieldValues[i].ID = mFieldValues[i].ID + 10;
}
for (int i = 0; i <= 9; i++)
{
Console.WriteLine(mFieldValues[i].ID);
}
Console.ReadLine();
}
}
}
Structs are passed as value, not reference. mFieldValues[i].ID = mFieldValues[i].ID + 10; will modify the copy in the list, not the struct itself. To modify the value in the list you need to create new TagFieldValue
for (int i = 0; i <= 9; i++)
{
mFieldValues[i] = new TagFieldValue { ID = mFieldValues[i].ID + 10 };
}
Or change TagFieldValue to class
private class TagFieldValue
{
public int ID { get; set; }
}
Structs aren't that flexible. the inputs can't be defined either, so if you want to do this, you should use a class instead. I had a similar problem and changing it to a class did not give any problems.

How to call a method that is on a Form from a class?

I have 2 forms on my project and like 5 classes. What I want to do is to call a method that is defined on a Form in a class, so it runs when I call it on my class. I thought about creating an instance of my Form in my class, but that would only create a "new Form" and it would be pointless. My other option is to make my form a static form, but I don't know how to do this. Thank you for your help!
EDIT
Here's the method that is defined on my Form:
public void fillMatrix(char[,] currentMatrix, int rows, int columns)
{
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < columns; j++)
{
string route = GameInstance.vexedGame.imgToShow(currentMatrix[i, j]);
DataGridVexed[j, i].Value = Bitmap.FromFile(route);
}
}
}
Very basic example, if I've understood your original request:
public class MyForm : Form
{
public A a = null;
public MyForm ()
{
A = new A(this); // pass an instance of the MyForm to the class
}
public void WowMethod(){
... something amazing ...
}
}
public class A
{
public MyForm associatedForm = null;
public A( MyForm f ){
associatedForm = f;
}
public void CallWowMethod()
{
associatedForm.WowMethod();
}
}

Categories

Resources