I have a project called FoodPantryGlobal, which contains all of the constants I will use.
I have another project called RegisterInput which uses FoodPantryGlobal.
In FoodPantryGlobal is an array called CityNames[], that RegisterInput needs to use in order to load a Combobox.
The problem I am having is CityNames[] seems to be empty to RegisterInput when called.
If I declare a local array, and use that every thing works fine.
I am betting it is something simple that I am missing.
FoodPantryGlobal has been added to the resources.
using System;
The code I am using for the Global.
namespace FoodPantryGlobals
{
public class GlobalConst
{
public const string excelFileName = "Food Pantry Registry.xlsm";
public const int cityNamesMembers = 4;
public readonly string[] cityNames = new string[cityNamesMembers] {"Hollans", "Roanoke", "Salem", "Vinton" };
}
public class GlobalProcedures
{
}
}
The code making trying to use CityNames.
using FoodPantryGlobals;
private void CboxCity_GotFocus(Object sender, EventArgs e)
{
const int members = GlobalConst.cityNamesMembers;
//string[] cityNames = new string[members] { "Hollans", "Roanoke", "Salem", "Vinton" };
//string city = FoodPantryGlobals.GlobalConst.cityNames[0];
int index = 0;
while (index < members)
{
string city = GlobalConst.cityNames[index];
CboxCity.Items.Add(city);
index = index + 1;
}
}
Just make cityNames static
public static readonly string[] cityNames = new string[] { "Hollans", "Roanoke", "Salem", "Vinton" };
and IMHO you can use foreach
foreach (var city in GlobalConst.cityNames) CboxCity.Items.Add(city);
or maybe even better
CboxCity.Items.AddRange( GlobalConst.cityNames);
maybe you should clear previous items before adding new ones
CboxCity.Items.Clear();
Related
UML is attached. I want to create a readonly property of pre which is an array of string. When I create an object in the main and try to set name and pre it is showing me an error.
UML
using System;
class Unit
{
private string _name;
private string[] _pre;
public Unit(string name, string[] pre)
{
_name = name;
_pre = new string[2];
}
public string Name { get { return _name; } }
public string[] Pre { get { return _pre; } }
}
class Program
{
public static void DisplayInfo(Unit[] _u)
{
for (int i = 0; i < 2; i++)
{
Console.WriteLine(_u[i].Name + _u[i].Pre);
}
}
static void Main(string[] args)
{
Unit[] unitarraytest = new Unit[2];
unitarraytest[0] = new Unit("test 1", "test 3");
unitarraytest[1] = new Unit("test 2", "test 4");
DisplayInfo(unitarraytest);
}
}
Your example makes little sense. You Unit constructor takes a parameter for "Pre", but immediately throws it away and allocates a new empty string array instead. It should probably be written like
class Unit
{
public Unit(string name, string[] pre)
{
Name = name;
Pre = pre;
}
public string Name { get;}
public string[] Pre { get;}
}
When creating Unit objects you actually need to create an array for the "Pre" parameter. Like new Unit("Name", new []{"pre1", "pre2"});
And when outputting the strings you need to access the individual strings in the array, or combine them to a larger string, for example like Console.WriteLine(_u[i].Name + string.Join(" , ", _u[i].Pre));
I'm trying to loop through an array of objects and print their properties from a different class.
My main class is
class Program
{
static void Main()
{
//This to be change to relative path
string Path = #"C:\Users\";
string[] lines = { }; ;
//Reading file
if (File.Exists(Path))
{
lines = File.ReadAllLines(Path);
StudentReport.ReadStudents(lines);
}
else
{
Console.WriteLine("The file does't exist");
}
//Printing Students
PrintStudent.Print(lines.Length);
}
}
I'm using this code to declare the array
public class StudentReport
{
public static void ReadStudents(string[] Lines)
{
//declare an array with the number of students
Student[] studentArray = new Student[Lines.Length];
int StudentCounter = 0;
foreach (string Line in Lines)
{
String[] Student = Line.Split(',');
//Calculating values
string ID = Student[0].PadLeft(10, '0');
string name = Student[1];
//Initialize the object
studentArray[StudentCounter] = new Student
{
FullName = name,
ID = ID,
};
StudentCounter++;
}
}
}
And I'm using this class to construct my student object
class Student
{
public string FullName { get; set; }
public string ID { get; set; }
}
To output the student object properties, I made another class. The problem is that I couldn't access the value of the objects array from my new class.
The class I made for outputting purposes is the following, but I cannot get the values. The error is 'Student does not contain a definition for student array
public class PrintStudent
{
public static void Print(int StudentCounter)
{
for(int i = 0; i > StudentCounter; i++)
{
Console.WriteLine(Student.studentArray[i].FullName);
}
}
}
Your error is Student does not contain a definition for studentArray. This is because your Student class does not have studentArray, only the properties FullName and ID. So accessing Student.studentArray[i] doesn't make sense.
Probably what you want is for ReadStudents to return the studentArray so it doesn't go out of scope by changing the method signature to return the Student[], and calling return studentArray at the end.
Then, you can pass your studentArray to your PrintStudent.Print method in the parameters.
By the way, the for(int i = 0; i > StudentCounter; i++) has a wrong < and will never run (lines.Length which is the StudentCounter will always be >= 0)
You can use studentArray.Length, or a foreach loop to iterate over this array, rather than pass the StudentCounter.
I'm trying to Path.Combine, but having highlighted string(appdatapath), helper say's that "a field initializer cannot reference the non-static field, method, or property'MySuperAPP.appdatapath' "
the code is :
string appdatapath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
string path = Path.Combine(appdatapath, "second/part/of/folderpath");
what i want is:
string path = "C:/Users/USER/AppData/Local/Some/Dir/"
what i tried :
string static appdatapath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
string static path = Path.Combine(appdatapath,"second/part/of/folderpath").ToString;
and
public static string GetMyLocalAppDir()
{
return Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData).ToString();
}
string path = Path.Combine(GetMyLocalAppDir(),"second/part/of/folderpath").ToString;
i think the variants that i'm tried may be wrong..)
need your advice) thank's!)
When you initialize a field (this mean: when you provide a dynamic field with a value at runtime) it must be a static value.
Therefore you must declare "appdatapath" as static.
public partial class MainWindow : Window
{
private static string appdatapath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
private (static) string path = System.IO.Path.Combine(appdatapath, "second/part/of/folderpath"); //make this static if you want that this field can't be changed.
public MainWindow()
{
InitializeComponent();
}
}
Also make sure your declaration is in the right order:
public or private static or not type e.g. string name of variable
Finaly: if you have more directory's to combine, put eacht part separately:
Path.Combine(appdatapath, "second", "part", "of", "folderpath")
public static void Read_bootup3_file()
{
qq = 0;
string downloadz2;
string fileNameSDcard = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "download.txt");
string CurrentContents;
CurrentContents = fileNameSDcard;
//CurrentContents = File.ReadAllText(fileNameSDcard);
File.WriteAllText(fileNameSDcard, CurrentContents);
using (StreamReader sr = new StreamReader(fileNameSDcard))
{
downloadz2 = sr.ReadToEnd();
}
//downloadz = downloadz2.ToCharArray();
qq = 0;
for (leep = 0; leep <= lotsize; leep++)
{
for (lep = 0; lep <= 20; lep++)
{
Tester.garage_array_database[lep, leep] = downloadz[qq].ToString();
qq++;
}
}
I'm looking for a way to initialize a new instance of a class with a string as its name in order for me to find that specific instance in a list at a later point.
Currently I have something along the lines of this code:
static List<ClassItem> classList = new List<ClassItem>();
private void updateClassList(Stream stream)
{
Message = Recieve(stream);
Interact(Message); //get the number of Classes about to be recieved
string ID;
string state;
for(int i = 0; i < numberOfClasses; i++)
{
Message = Recieve(stream);
interpretClassProperties(Message, out ID, out State);
ClassItem ID = new ClassItem(ID, state); //incorrect code
classList.Add(ID); //add new instance to list
}
}
Obviously this isn't going to work as I can't use a variable to initialise a class instance, however logically it shows what I want to achieve. Each loop will add an instance of ClassItem (with the appropriate ID value as a name) to the classList so I can find it later.
What should I look into in order to achieve this?
Any feedback appreciated, including any warnings of future problems I may have in approaching the problem in this fashion. (I.e. finding a class instance in a List by name).
Use Activator.CreateInstance:
public static ObjectHandle CreateInstance(
string assemblyName,
string typeName
)
You know your assembly name and receive the class name (type name).
MSDN: https://msdn.microsoft.com/en-us/library/d133hta4(v=vs.110).aspx
Sample code:
static List<object> classList = new List<object>();
private void updateClassList(Stream stream)
{
Message = Recieve(stream);
Interact(Message); //get the number of Classes about to be recieved
string id;
for(int i = 0; i < numberOfClasses; i++)
{
Message = Recieve(stream);
interpretClassProperties(Message, out id);
classList.Add(Activator.CreateInstance("AssemblyName", id).Unwrap());
}
}
Is something like this what you're looking for? Beware, though, this will likely create a memory nightmare in time unless you are certain to dereference your instances from the static list.
public class ClassWithIds
{
public static List<ClassWithIds> Instances = new List<ClassWithIds>();
private static int _idSeed = 0;
private readonly string _name;
public string Name
{
get
{
return _name;
}
}
private static int NextId()
{
return Interlocked.Increment(ref _idSeed);
}
public ClassWithIds()
{
_name = this.GetType().FullName + " Number " + NextId();
Instances.Add(this);
}
}
I'm trying to add new values input by the user on a separate windows form into the following array:
public class NameValue
{
public string Name;
public string Value;
public NameValue() { Name = null; Value = null; }
public NameValue(string name, string value) { Name = name; Value = value; }
}
public class DefaultSettings
{
public static NameValue[] Sites = new NameValue[]
{
new NameValue("los angeles, CA", "http://losangeles.craigslist.org/"),
};
public static NameValue[] Categories = new NameValue[]
{
new NameValue("all for sale", "sss"),
};
}
How do I add the new values to the array while keeping the values of the old array?
Edit
I tried using Mr. Noren's function:
static void AddValueToSites(NameValue newValue)
{
int size = DefaultSettings.Sites.Length;
NameValue[] newSites = new NameValue[size + 1];
Array.Copy(DefaultSettings.Sites, newSites, size);
newSites[size] = newValue;
DefaultSettings.Sites = newSites;
}
private void button1_Click(object sender, EventArgs e)
{
NameValue newSite = new NameValue("Test, OR", "http://portland.craigslist.org/");
AddValueToSites(newSite);
Close();
}
But that's not working... The class I am getting data from is:
public partial class Location : Office2007Form
{
public Location()
{
InitializeComponent();
}
static void AddValueToSites(NameValue newValue)...
private void button1_Click(object sender, EventArgs e)...
}
You cannot change the size of an array, ever. You would need to use something like a List for that.
Since you're using name/value pairs you should consider using Dictionary<TKey,TValue>.
Finally, if you're looking to have different classes contribute to the contents of the arrays, then that's not going to happen.
You can't add to an array, whether it's in another class or not.
Use List<NameValue> instead of NameValue[] and then you can use Sites.Add(...).
If you're absolutely married to the idea of using an array versus some more flexible collection, you should implement some AddX() methods in the class that is defining the base values. Those methods would take care of inserting the new values in the array. If you're not concerned with multithreading issues, it can be very simple:
(Warning: code is from my head and not tested)
static void AddValueToSites(NameValue newValue)
{
int size = Sites.Length;
NameValue[] newSites = new NameValue[size+1];
Array.Copy(Sites, newSites, size);
newSites[size] = newValue;
Sites = newSites;
}
And again for Categories.
Like others suggested, using List<NameValue> or Dictionary<string,string> would be options that would be more fluid. These already have Add, Remove, Contains, etc. - basically all you need when you need to manipulate arrays.
Arrays are not mutable in place, so if you resize them (using any approach) it'll result in a different instance being created (this is what happens in VB.NET's ReDim but they hide it from you).
The simplest way to resize an array in C# is to use the Concat extension method (requires System.Linq):
string[] myArray = new string[] { "Hello", "World" };
myArray = myArray.Concat(new string[] { "Something", "new" };
myArray will now be 4 elements deep. I don't think this will work between classes though (haven't tried though).