C# - Compile variable as name/code - c#

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.

Related

How to create arrays with different names in C#?

I'm currently working on a game (console application) with 25 Chunks, that are 5x5. All Chunks are in a List(5x5) witch is the Level in the end.
I do not want to declare all arrays. I would like to write a method in witch the arrays will be declared but with changing names.
For example:
- ac_Array_1
- ac_Array_2
static void Level()
{
List<char[,]> ol_Level = new List<char[,]>();
}
static void Spielblock()
{
int i_Stelle = 1;
string s_ArrayName = "ac_Chunk_" + i_Stelle;
i_Stelle++;
char[,] /*NAME*/ = new char[5, 5];
}
Try something like this:
int numOfLevels = 5;
Dictionary<string, char[,]> ol_Level = Enumerable
.Range(1, numOfLevels)
.ToDictionary(k => $"ac_Chunk_{k}", v => new char[5,5]);
ac_Chunk = ol_Level["ac_Chunk_1"];//char[5,5]
for (int i_Row = 0; i_Row < ac_Chunk.getLength(0); i_Row++)
{
for (int i_column = 0; i_column < ac_Chunk.getLength(1); i_column++)
{
ac_Chunk[i_Row, i_column] = '#';
}
}
...
levels:
ac_Chunk_1, ac_Chunk_2, ac_Chunk_3, ac_Chunk_4, ac_Chunk_5
n.b. using System.Linq and c# 6.0 $ interpolation
To have a dynamic variable name like you are requesting is not a simple thing to accomplish.
Generally, variable names are known at compile time, and the compiler can make optimizations using that information. What you are requesting would keep that from happening.
So the suggestions that you are seeing: create a variable, such as a dictionary, known when compiling and writing the code. Make that variable one that can dynamically expand to contain as many "chunks" as you'd like. And with a Dictionary<string, char[,]> you can even give each of those chunks a name. They won't be individual variable names, but it will let you access them by string/name and iterate through the collection in different ways.
To add a detail to Johnny's answer, at any point you can use
var ac_chunk = ol_Level["ac_Chunk_1"];
if you want to repeatedly access an individual chunk.
Or, even easier, just keep using ol_Level[$"ac_Chunk_{chunkNumber}"]

How can I find an Index in an array using a value that exists in another array and THAT array?

I have a c# class that looks like this:
public class MemberData
{
public int meme_ck;
public string meme_name;
public bool meme_active;
public MemberData(int ck2, string name2, bool active2)
{
meme_ck = ck2;
meme_name = name2;
meme_active = active2;
}
}
I have made two arrays out of that class:
private MemberData[] memarray1 = new MemberData[10000];
private MemberData[] memarray2 = new Memberdata[10000];
Over the course of my application I do a bunch of stuff with these two arrays and values change, etc. Member's name or active status may change which results in the ararys becoming different.
Eventually I need to compare them in order to do things to the other one based on what results are kicked out in the first one.
For example, member is de-activated in the first array based on something application does, I need to update array 2 to de-activate that same member.
I am trying to use some database design philosphy with the int CK (contrived-key) to be able to rapidly look up the entry in the other array based on the CK.
Since I can't figure it out I've had to resort to using nested for loops like this, which sucks:
foreach (Memberdata md in memarray1)
{
foreach (Memberdatamd2 in memarray2)
{
if (md.ck = md2.ck)
{
//de-activate member
}
}
}
Is there a better way to do this? I just want to find the index in the second array based on CK when I have the CK value from the first array.
Any other tips or advice you have about structure would be appreciated as well. Should I be using something other than arrays? How would I accomplish this same thing with Lists?
Thanks!
Should I be using something other than arrays?
Yes. Don't use arrays; they are seldom the right data structure to use.
How would I accomplish this same thing with Lists?
Lists are only marginally better. They don't support an efficient lookup-by-key operation which is what you need.
It sounds like what you want is instead of two arrays, two Dictionary<int, MemberData> where the key is the ck.
I totally agree with Eric Lippert's answer above. It is better you do not use Array.
Same thing can be achieved using List<MemberData>. You can use LINQ as well to query your DataStructure.
Following is one of the way just to achieve your result using array
class Program
{
static MemberData[] memarray1 = new MemberData[10000];
static MemberData[] memarray2 = new MemberData[10000];
static void Main(string[] args)
{
for (int i = 0; i < memarray1.Length; i++)
{
memarray1[i] = new MemberData(i + 1, "MemName" + i + 1, true);
memarray2[i] = new MemberData(i + 1, "MemName" + i + 1, true);
}
// SIMULATING YOUR APP OPERATION OF CHANGING A RANDOM ARRAY VALUE IN memarray1
int tempIndex = new Random().Next(0, 9999);
memarray1[tempIndex].meme_name = "ChangedName";
memarray1[tempIndex].meme_active = false;
//FOR YOUR UDERSTADNING TAKING meme_ck IN AN INTEGER VARIABLE
int ck_in_mem1 = memarray1[tempIndex].meme_ck;
//FINDING ITEM IN ARRAY2
MemberData tempData = memarray2.Where(val => val.meme_ck == ck_in_mem1).FirstOrDefault();
// THIS IS YOUR ITEM.
Console.ReadLine();
}
}

Use a variable value as a part of array name

I've read other similar Questions. But, All of them use bash. IDK anything about that language.
The Thing I want to do is:
int i=0; //Value of i will change as I want to use it in loop
string name="c"+i;
double a= name[i]; //The real name of arrays I have declared are: c0[],c1[] etc
It gives error: "Project" does not contain a definition for "name"
So, How do I acheive this?
Obviously you have a set of variables, all sharing a common name, e.g. MyVariable1, MyVariable2, etc.
Instead of having so many similar variables, you should use an array, or in your case an array of arrays:
var myVariableArray = new double[][] { c[0], c[1], ... };
Now you can easily acces the i-th number within that array:
double a = myVariableArray[i][i];
Alternativly if those variables actually are members (fields or propertiers) within your class, you can also use reflection to get the right member from a string:
var fields = typeof(MyType).GetField(name + i);
double b[];
if(field != null)
b = (double[]) field.GetValue(instanceOfMyType, null);
else
{
var prop = typeof(MyType).GetProperty(name + i);
if(prop != null)
b = (double[]) prop.GetValue(instanceOfMyType, null);
}
a = b[i];
However such a data-structure is bad design, you should go with an array (or list) of members, instead of having dozens of similar members.
You need an array of arrays (two-dimensional arrays), don't you?
To create an array of arrays, do this:
double[][] twoDArray = new double[][x];
where x is the number of arrays you want.
Now you can populate it with some arrays like this:
twoDArray[0] = new double[] {1.0, 1.1, 1.2};
twoDArray[1] = new double[] {7.7, 8.8, 9.9};
To access an array in the 2D array, you don't even need name, you just use i directly!
double[] oneOfTheArrays = twoDArray[i];
double a = oneOfTheArray[0];
Or more simply:
double a = twoDArray[i][0];

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

c# basic formatting question

If I wanted to swap out part of a statement with a variable i.e.
tempCube.transform.parent = row(var would need to go here ie an int that is iterated with a for loop).transform;
How would I write this. Sorry for the really basic question, I have been using other languages too long and now I have gone back to c# I have almost forgotten everything I had learned.
"(i)" is the bit I want to swap out with a variable
eg
for(int i = 1; i <= 3; i++){ print row*(i)*.transform; }
Console:
(1,2,3)
(2,3,4)
(4,5,6)
You mean like:-
row1.transform;
row2.transform;
row3.transform;
...
If so, no, you can't replace that text at runtime. You should use a collection. Ideally make an IEnumerable out of them and use foreach:-
foreach (var x in new { row1, row2, row3 ... })
{
x.transform;
}
I am not sure what you mean, i hope you want to specify the index, is this what you are looking for (index is the int you mentioned)
tempCube.transform.parent = row[index].transform;

Categories

Resources