How can I compose variables names through loop in C#? - c#

I have rewritten this question because not everyone understood. Hope it's ok, it's the same main problem.Very sorry
I have a winform with 15 progress bars called: "baraClasa1", "baraClasa2", "baraClasa3" ... "baraClasa15". I have to assign the .VALUE property (as in int) to all of them, from some database records. (The records access the different values from different time periods)
I was thinking that maybe it is possible to use a loop to assign the .Value property to all of them by doing something like:
for(int i=0; i<value; i++)
{
"baraClasa+i".Value = 20 + i;
}
Is it possible to compose the name of the variables like that?
I don't know much about dictionaries, lists but looking into. If nothing works il just do the ugly:
int value = 20;
baraClasa1 = value;
baraClasa2 = value +1;....
Thank you for all help

You have to do a little reflection.
public string variable0, variable1, variable2, variable3, variable4, variable5;
private void button1_Click(object sender, EventArgs e)
{
for (int i = 0; i < 6; i++)
{
//pretending my variable names are variable1, variable2.. ("variable" is NOT an array! just the "assign" variable)
System.Reflection.FieldInfo info = this.GetType().GetField("variable" + i.ToString());
// replace "testing" with the value you want e.g. assign[i]
info.SetValue(this, "testing");
}
// Do something with your new values
}
No need to use reflection with the updated question. The control collection has a built in find for getting a control by the name string.
for (int i = 0; i < 6; i++)
{
ProgressBar bar = (ProgressBar)this.Controls["baraClasa" + i.ToString()];
bar.Value = 50;
}

This is a design problem. Create a collection for items with common use (like progress bars for that matter) and iterate over the collection to perform actions on them.
If these are prorgress bars you might want to use an event-driven design (another link) to update their progress, meaning that each time a bar has made some progress, the event for the progress will send an update only to that bar, and not iterate over the entire list.
You may want to read an introduction to event driven programming in C# before re-factoring your code.

It really isn't possible in C# to refer to local variables in a dynamic fashion as you are trying to do. Instead what you would do in C# is store the value in a dictionary where the key can be generated in a dynamic fashion.
For example let's say all of your variable1, variable2, ... variableN were of type int. Instead of
int variable1 = 0;
int variable2 = 0;
...
int variableN = 0;
You would instead do the following
Dictionary<string, int> map = new Dictionary<string, int>();
for (int i = 0; i < N; i++) {
map[i.ToString()] = 0;
}
If the values are a of a fixed number and always linear in progress it may make sense to use an array instead of a dictionary
int[] array = new int[N];
for (int i = 0; i < N; i++) {
array[i] = 0;
}

You can't do it that way. You need an array. Every time you notice yourself having a variable2, you need an array. You may not know it yet, but you do.

No, you can't do it in C#, it's syntactically impossible. But if you want access form controls which has different names like this you can do the following:
for(int i=0; i<20; i++)
{
var name = "variable" + i;
this.Controls[name].Text = "etc..." // here you can access your control
}

If you want to have names for your objects, use a dictionary:
Dictionary<string, type> myDict = new Dictionary<string, type>()
string naming = "MyPattern{0}";
for (int i = 0; i <value; i++) {
myDict.add(string.Format(naming, i.ToString()), assign[i]);
}
And then you can access them by doing, for example:
myDict["MyPattern1"]
However, I suggest you would be better off using a collection like a List or array.

Arrays, lists, dictionaries, hash maps... collections in general are what you would use here. For example, if you have a dictionary, then it consists of key/value pairs. So a dictionary might look like this:
var variable = new Dictionary<int, string>();
Where the int is the key for any given entry, and the string is the value. You'd assign values in something like this:
for(int i = 0; i < value; i++)
variable.Add(i, assign[i]);
Of course, since i is just an incrementing integer in this case (unless you have some other key in mind?), then it works just as well as an indexer on a list. Something like this:
var variable = new List<string>();
for (int i = 0; i < value; i++)
variable.Add(assign[i]);
In both cases, you'd access the assigned value later by referencing its key (in a dictionary) or its index (in a list, or any array):
var someOtherVariable = variable[x];
Where x is an integer value present in the dictionary's keys or in the array's size.

If you can put names of all variables in an array such as 'variable', and they are unique, you can try to use dictionary :
Dictionary<object, object> dictionary = new Dictionary<string, object>();
for(int i=0; i<value; i++)
{
dictionary.Add(variable[i], assign[i]);
}

Related

creating a custom list windows phone 8.1

here is the code adding data to the list, after which i return the list. Problem is that the last set of data seems to be overwriting everything else in the list
for (int k=0; k < jsonObject["mydetails"].GetArray().Count; k++)
{
//add the corresponding data from the sample array
obj.accountNumber = jsonObject["mydetails"].GetArray()[k].GetObject()["id"].GetString();
obj.accountName = jsonObject["mydetails"].GetArray()[k].GetObject()["name"].GetString();
obj.accountBall = jsonObject["mydetails"].GetArray()[k].GetObject()["age"].GetString();
mylist.Add(obj);
}
Your code isn't adding any new objects to the list, it modifies and adds the same object. In the end, the list contains X references to the same object instance.
In general it is consider bad practice to declare a variable outside the scope in which it is used. You could have avoided this problem by writing:
var myArray=jsonObject["mydetails"].GetArray();
for (int k=0; k < myArray.Count; k++)
{
var myJsonObject=myArray[k].GetObject();
var obj=new MyAccountObject();
obj.accountNumber = myJsonObject["id"].GetString();
...
}
Notice that instead of calling GetArray() and GetObject() in each line (essentially doing the job of extracting the array multiple times) I stored them in separate variables. This will result in far less CPU and memory usage.
You always add the same object obj to the list. You need to create a new in the top of the loop.
for (int k=0; k < jsonObject["mydetails"].GetArray().Count; k++)
{
obj = new ObjectType(); // you know better the type of the object you want to create.
//add the corresponding data from the sample array
obj.accountNumber = jsonObject["mydetails"].GetArray()[k].GetObject()["id"].GetString();
obj.accountName = jsonObject["mydetails"].GetArray()[k].GetObject()["name"].GetString();
obj.accountBall = jsonObject["mydetails"].GetArray()[k].GetObject()["age"].GetString();
mylist.Add(obj);
}
Without the the line obj = new ... you change the properties accountNumber, accountName and accountBall of the same object instance. At the end you add always that object reference to the list. So it seems that the last run of the loop changes all objects.

Manipulating Values in Dictionary

So I have a dictionary whose index is an int, and whose value is a class that contains a list of doubles, the class is built like this:
public class MyClass
{
public List<double> MyList = new List<double>();
}
and the dictionary is built like this:
public static Dictionary<int, MyClass> MyDictionary = new Dictionary<int, MyClass>();
I populate the dictionary by reading a file in line by line, and adding the pieces of the file into a splitstring, of which there is a known number of parts (100), then adding the pieces of the string into the list, and finally into the dictionary. Here's what that looks like:
public void DictionaryFiller()
{
string LineFromFile;
string[] splitstring;
int LineNumber = 0;
StreamReader sr = sr.ReadLine();
while (!sr.EndOfStream)
{
LineFromFile = sr.ReadLine();
splitstring = LineFromFile.Split(',');
MyClass newClass = new MyClass();
for (int i = 1; i < 100; i++)
{
newClass.MyList.Add(Convert.ToDouble(splitstring[i]));
}
MyDictionary.Add(LineNumber, MyClass);
LineNumber++;
}
}
My question is this: is I were to then read another file and begin the DictionaryFiller method again, could I add terms to each item in the list for each value in the dictionary. What I mean by that is, say the file's 1st line started with 10,23,15,... Now, when I read in a second file, lets say its first line begins with 10,13,18,... what I'm looking to have happen is for the dictionary to have the first 3 doubles in its value-list (indexed at 0) to then become 20,36,33,...
Id like to be able to add terms for any number of files read in, and ultimately then take their average by going through the dictionary again (in a separate method) and dividing each term in the value-list by the number of files read in. Is this possible to do? Thanks for any advice you have, I'm a novice programmer and any help you have is appreciated.
Just Replace
newClass.MyList.Add(Convert.ToDouble(splitstring[i]))
with
newClass.MyList.Add(Convert.ToDouble(splitstring[i]) + MyDictionary[LineNumber].GetListOfDouble()[i])
and then replace
MyDictionary.add(Linenumber, Myclass)
with
MyDictionary[linenumber] = MyClass
Just makes sure that the MyDictionary[LineNumber] is not null before adding it :)
Something like this would work
If(MyDictionary[LineNumber] == null)
{
MyDictionnary.add(LIneNUmber, new List<double>());
}
If(MyDictionary[LineNUmber][i] == null)
{
return 0;
}
My solution does not care about list size and it done at reading time not afterward, which should be more efficient than traversing your Dictionary twice.
var current = MyDictionary[key];
for(int i = 0; i < current.MyList.Length; i++)
{
current.MyList[i] = current.MyList[i] + newData[i];
}
Given both lists have same length and type of data.
You can get the custom object by key of the dictionary and then use its list to do any operation. You need to keep track of how many files are read separately.

Can we create variables at run time

In c# why is it not allowing to create variable names dynamically? I am trying something like this:
for (int i = 0; i < ceoList.Count; i++)
{
List<VP> "vp" + i = new List<VP>();
}
I want to generate variable names at run time. Like "vp" + i here.
You don't want to create variable names at run time, you want to create data structures.
List<List<VP>> vps = new List<List<VP>>
for (int i = 0; i < ceoList.Count; i++)
{
vps.Add( new List<VP>());
}
What you are trying to accomplish is not a valid programming syntax, and will not compile in any imperative programming language compiler!
What you want is a way to name references to a set of objects of the type List, so to achieve that I would recommend you to check it out HashTables in the namespace System.Collections.
Hashtable vpTable = new Hashtable();
for (int i = 0; i < ceoList.Count; i++)
{
vpTable.add("vp" + i, new List());
}

C# - Compile variable as name/code

Since I couldn't explain very good in my last question and I didn't get an answer that could satisfy me, I decided to open a new one. Straight to the point, what I'm basically trying to do is compiling a variable (the value it holds) as a part of code (and specificly in my case referencing another variable)
Say I have:
int var_1, var_2, var_3 ... var_10;
for (int i = 1; i <= 10; i++)
{
var_%i%=20; //if i is 1, then var_1's value will be set to 20, if i is 2, then var_2's value will be set to 20. So basically this loop sets the value of var_1 .. var_10 to 20
}
I can explain in an even simpler way, if in any case the latter is not clear.
int var_5;
int SomeOtherVar = 5;
var_%SomeOtherVar% = 10; // so var_5 (where 5 is the value of SomeOtherVar) is set to 10
Is this doable and if it is, what's the approach?
No you can't do that, why dont you use an array?
int[] array = new int[3];
for (int i = 0; i < array.Length; ++i)
{
array[i] = 20;
}
Hope it helps.
It's not doable. Use an array instead. The type is int[] but I suggest you go read a tutorial about arrays to understand how to create and use them.
I can't think of a situation where you'd need to do this. If you wish to store values against a consecutive list of numbers, use an array. Otherwise you could use a Dictionary. For example to store "var1" = 20, "var2" = 20 as in your question, you could do this:
Dictionary<string, int> dict = new Dictionary<string, int>();
for (int i = 1; i <= 10; i++)
{
dict.Add("var" + i.ToString(), 20);
}
Some examples of usage:
dict["var1"] // 20
dict["var2"] // 20
dict.ContainsKey("var3") // true
dict.ContainsKey("var99") // false
Note: I'm concatenating the string "var" with the int from the loop just to demonstrate that you can use arbitary strings as keys to store / lookup the values. In this case it's a bit of a strange thing to do, and you'd probably be best sticking to a normal array, but my example shows how a dictionary could work with more complex keys.
If you want to bypass static type checking and you feel like creating some coding horror, you can use ExpandoObject combined with the dynamic keyword. Won't let you set variables in your scope, but will technically let you declare your own ones. Note that in my example I cast it to IDictionary<string, object> because I create its members' names at runtime from a string. What the following method does is create twenty members and assign their values from 0 to 19.
static dynamic SetVariables(IEnumerable<int> range)
{
const string variableName = "var_";
var expandoDictionary = new ExpandoObject() as IDictionary<string, object>;
foreach (var i in range)
expandoDictionary[variableName + i] = i;
return expandoDictionary;
}
You can then access the members easily this way:
var container = SetVariables(Enumerable.Range(0, 20));
var value13 = container.var_13;
Please note that I do not recommend this usage, and I'd stay away from dynamic as much as I can. However, for the sake of problem solving, this can be seen as one unsafe but partial solution.

How can i construct a variable name in code from a string?

I have a number of variables named test1....test10 they are all declared as a string.
what I want to do is access them from inside a loop using the loop counter something like this:
string test1;
//...
string test10;
for (int i = 1; i < 10; i++)
{
test + i.ToString() = "some text";
}
any idea how I could do this?
this is a WPF .net 4 windows App.
Simple answer: don't have 10 variables, have one variable which is a collection:
List<string> test = new List<string>();
for (int i = 1; i < 10; i++)
{
test.Add("some text");
}
Having lots of variables which logically form a collection is a design smell.
(If you really have to do this, you could use reflection. But please don't.)
You simply can't, use a List or a String-Array for this purpose.
List
List<String> myStrings = new List<String>();
for (Int32 i = 0; i < 10; i++)
{
myStrings.Add("some text");
}
String-Array
String[] myStrings = new String[10];
for (Int32 i = 0; i < myStrings.length; i++)
{
myStrings[i] = "some text";
}
Try adding them to an array of string[] or simply create a List<string> list = new List<string>();.
With the list, you can iterate easily.
This is not really possible, unless you use the dynamic keyword, and then you will get a property instead of a true variable. Take a look at ExpandoObject, it will allow you to add properties based on a string variable.
In your case, as other have said, you really should use a List<string>
For something as simple as 10 items, an array is the best way to go. Fast and easy.

Categories

Resources