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

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.

Related

Remove part of a string from List<string>

I have a List<string>, the string part representing filenames that I need to filter out: anything that comes before the character '&' included must be erased.
List<string> zippedTransactions = new List<string>();
zippedTransactions.Add("33396&20151007112154000549659S03333396SUMMARIES.PDF");
zippedTransactions.Add("33395&20151007112400000549659S03333395SUMMARIES.PDF");
zippedTransactions.Add("33397&20151007112555000549659S03333397SUMMARIES.PDF");
// desired output:
// "20151007112154000549659S03333396SUMMARIES.PDF";
// "20151007112400000549659S03333395SUMMARIES.PDF";
// "20151007112555000549659S03333397SUMMARIES.PDF"
NOTE: I don't want to give it the classic iterative-style look, since C# provides for plentiful of functional interfaces to interact with this sort of data structure, I want to start using it.
Here is one Linq approach with RegEx
Transactions = Transactions.Select(x => Regex.Replace(x, ".*&", string.Empty)).ToList();
That's more fault tolerant compared to Split('&')[1] in case there is no & in your filename
Try this
for (int i = 0; i < zippedTransactions.Count; i++)
{
zippedTransactions[i] = zippedTransactions[i].Split('&')[1];
}
If you happen to have visual studio, and a version that supports C# Interactive, I suggest you try this.
> zippedTransactions = new List<string>() {
"33396&20151007112154000549659S03333396SUMMARIES.PDF",
"33395&20151007112400000549659S03333395SUMMARIES.PDF",
"33397&20151007112555000549659S03333397SUMMARIES.PDF"
};
>
> zippedTransactions.Select(dirname => dirname.Split('&')[1])
Enumerable.WhereSelectListIterator<string, string> { "20151007112154000549659S03333396SUMMARIES.PDF", "20151007112400000549659S03333395SUMMARIES.PDF", "20151007112555000549659S03333397SUMMARIES.PDF" }
>
And even if you don't, you can get an idea of what's happening just by looking at the code.
The WhereSelectListIterator is a data structure holding the logic you intend to execute on the data structure. It is evaluated (read: the loop actually happens) only when you consume it (for example, calling .ToList() at the end).
This code will only take the second element coming after splitting the string on '&', so you might wanna generalize it or tune it for your requirements.
Use string.Split to split the string at the desired character and retrieve the portion that you want:
foreach (var item in zippedTransactions)
{
string[] result = item.Split('&');
Console.WriteLine(result[1]);
}
You can use the string.IndexOf function to find the location of a character in the string and then use string.Remove to remove the characters up to that point:
for(int i =0; i < zippedTransactions.Count; i++)
{
int count = zippedTransactions[i].IndexOf("&") + 1;
zippedTransactions[i] = zippedTransactions[i].Remove(0, count);
}
following code will help you
for (int i = 0; i < zippedTransactions.Count; i++)
{
string[] result = zippedTransactions[i].Split('&');
zippedTransactions[i] = result[result.Length-1];
}

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());
}

How can I compose variables names through loop in 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]);
}

Two lists with a relationship, how to display them to the user?

My problem is that I want to make a program that uses two lists, which is almost impossible for me to understand. Okay, so the deal is that I want to make a program where you first type in a city name and then the temperature for the city. This is where the relationship comes from.
I have started by making a "list class", which looks like this:
class citytemp
{
private string city;
private double temp;
public citytemp(string city, double temp)
{
this.city = city;
this.temp = temp;
}
public string City
{
get { return city; }
set { city = value; }
}
public double Temp
{
get { return temp; }
set { temp = value; }
}
}
Then I make the list in the program like this
List<citytemp> temps = new List<citytemp>();
Which all looks good to me. But when I'm trying to show the user the list nothing shows up. I use these lines to show it:
for (int i = 0; i > temps.Count; i++)
{
Console.WriteLine(temps[i].City, temps[i].Temp);
}
BTW: I add "things" to the list by these rows:
temps.Add(new citytemp(tempcity, temptemp));
...where tempcity and temptemp are temporary variables. They are only there to make it more simple for me to add them to the list, since I'm using a switch statement to add them to the list.
To make things more clear, my problem is that I don't know how I'm suppose to show the list to the user in the program.
Your problem is in the for loop. Change it to this
for (int i = 0; i < temps.Count; i++)
i.e. change the greater than > operator to a less than <
You have an error in your for loop.
for (int i = 0; i > temps.Count; i++)
it should be:
for (int i = 0; i < temps.Count; i++)
First of all, I'm not sure what you mean by "2 lists" as you only have one list in your code.
However, the problem you're having with "nothing shows up" is easy to fix.
This line of code:
for (int i = 0; i > temps.Count; i++)
Should be read as follows:
i = 0;
while (i > temps.Count)
{
... rest of your loop body here
i++;
}
if you read this, you'll notice that the second part of the for statement is not when to terminate but how long to keep going.
Change it to this, and you should be good:
for (int i = 0; i < temps.Count; i++)
^
+-- changed from >
I think a hashtable, specifically a dictionary would help you here:
var cityTemps = new Dictionary<string, double>();
cityTemps.Add("TestCity", 56.4);
foreach (var kvp in cityTemps)
Console.WriteLine("{0}, {1}", kvp.Key, kvp.Value);
In addition to the loop that has been mentioned, be careful withConsole.WriteLine because it takes in a String as first argument which it assumes is a format and object[] params as a second parameter. When you pass temps[i].City to it since its String it will think that its the format and temps[i].Temp is the parameter and won't display correctly.
What you want instead:
Console.WriteLine("City: {0} Temp: {1}", temps[i].City, temps[i].Temp);
Here I am using "City: {0} Temp: {1}" as the format for the string and the proper parameters.
This answer is to save you a headache later on wondering why only the city name is being displayed.

C# increase length of a string array [duplicate]

This question already has an answer here:
Closed 10 years ago.
Possible Duplicate:
how to inset a new array to my jagged array
i have a problem, where i dont know how i can make a string array variable in array length.
i have this code now below:
string[] p = new string[10];
int num = 0;
foreach (Product products in GetAllProducts())
{
//do something
p[num]= "some variable result"
num++
}
The problem is, that i dont know how many of "p" i will get, although i know it atleast will be less than 10.
but if i put it on 0, i will get an error when i start it, because it doesn't know the "p[num]"
So i am looking for some way to make "p" have a variable length.
anyone could help me out a bit? thanx
============Solved==========
List<string> p = new List<string>();
int num = 0;
foreach (Product products in GetAllProducts())
{
string s= null;
//do something ( create s out of multiple parts += s etc.)
p.add(s)
num++
}
thanx to solution poster
Use an List<string> instead of an array, if you do not know the number of items you will need to add.
Your array length cannot be modified after it has been instantiated. Use ArrayList or Generic Lists.
var p = new new List<string>(10);
foreach (Product products in GetAllProducts())
{
//do something
p.Add("some variable result");
}
What does GetAllProducts() return? Does it have a count or a length?! You should call that first, save it in a variable, get the count/length and then declare your array!
There's two solution.
If you want to keep using array :
int num = 0;
var list = GetAllProducts();
string[] p = new string[list.Length]; // Or list.Count if this is a collection
foreach (Product products in list)
{
//do something
p[num] = "some variable result";
num++;
}
Otherwise you should use a List like this :
List<string> p = new List<string>();
foreach (Product products in GetAllProducts())
{
//do something
p.Add("some variable result");
}
Use Array.Resize() method, which allows to resize it (by n number of indexes).
In my exmaple I will reize by 1 on each step of the way:
string[] array = new string[3]; //create array
for (int i = 0; i < 5; i++)
{
if (array.Length-1 < i) //checking for the available length
{
Array.Resize(ref array, array.Length + 1); //when to small, create a new index
}
array[i] = i.ToString(); //add an item to array[index] - of i
}
Because your code is using a foreach on the result from GetAllProducts, then GetAllProducts must be returning a IEnumerable collection. Probably the best solution would be to simply assign the result of GetAllProducts to such a collection. For example, perhaps it already returns a list of strings? So you can do:
List<string> strings = GetAllProducts();
There is no need to have a foreach loop to create an array when you already have a collection anyway being returned from GetAllProducts.
Or simply:
var strings = GetAllProducts();
to let the compiler work out the type of strings.
Most things you can do with an array you can also do with a List, and some more (such as adding items to the end of the List).
Perhaps you can post the signature of GetAllProducts (especially its return type) so we can better advise you?
I see many gave you the right answer which is the use of Lists. If you still need an array in the end, you can easily convert your list into an Array like this :
string[] tempArray = myList.ToArray();

Categories

Resources