2

I'm coming from a Python background and am dealing with code that creates many variables with the same name + an integer attached to the end, and need to replicate Python's f'something here {variable}' method in C#. How can I do this?

i.e.

int num1 = 1;
int num2 = 2;
int num3 = 3;
int num4 = 4;

etc...

is there a way to do something like

for (int i=1;i<5;i++) 
{
    int f'num{i}' = i;
}
kashmoney
  • 412
  • 1
  • 5
  • 17
  • Please explain what you mean by "create variables", member variables of some object? local variables you can use later in code? – X39 Sep 25 '18 at 20:53
  • you can, by using 'reflection' (that's how you can do some programming by dynamically creating or accessing variables). Though there are many cases where you should (for simplicity and safety) try to change your design, by using an array for instance. Your example is simple enough to go with the array (or other Collection-like) way. – Pac0 Sep 25 '18 at 20:53
  • Possible duplicate of [How do I name variables dynamically in C#?](https://stackoverflow.com/questions/5033675/how-do-i-name-variables-dynamically-in-c) – Servy Sep 25 '18 at 20:54
  • 6
    Why dont you use arrays or lists? – Hossein Sep 25 '18 at 20:54
  • Do you need to use this? You could probably utilize [arrays](https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/arrays/single-dimensional-arrays). If you really need to use it, take a look at [reflection](https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/reflection). [This SO thread](https://stackoverflow.com/questions/2012363/creating-an-instance-of-variable-with-reflection#2012371) could be useful. – SoptikHa Sep 25 '18 at 20:54
  • 1
    No there isn't, but maybe this is an XY problem - what are you really trying to do? – TypeIA Sep 25 '18 at 20:55
  • I don't think this is a duplicate of that question, presumably he already has the first block and wants the second, the answers in the dupe don't apply to this. – BradleyDotNET Sep 25 '18 at 20:56
  • I haven't used arrays or lists as I was trying to show a brief example that illustrated the problem. In practice, I'm dealing with legacy code and trying to easily simplify more complex objects such as DataTable dt1 = new DataTable(), DataTable dt2 = new DataTable(), etc, whose corresponding tables are unrelated to the index – kashmoney Sep 25 '18 at 20:57
  • 1
    Honestly I would simply use a collection, which would allow you to store the contents of a loop with the indexed position representing a variable name, per se. However, that would reveal that you have tightly bound code to an indexed position, so you may want to rethink your intent for a more expressive design. – Greg Sep 25 '18 at 20:57
  • 1
    @BradleyDotNET The answers to the duplicate say exactly what you posted in your answer. If you don't think that they answer the question, then why did you just repeat them in your answer? – Servy Sep 25 '18 at 21:03
  • @Servy Not a single answer in https://stackoverflow.com/questions/5033675/how-do-i-name-variables-dynamically-in-c even *mentions* reflection because that post is about creating variables, not accessing them. – BradleyDotNET Sep 25 '18 at 21:05
  • 1
    @BradleyDotNET Yes, just like this post, because they're duplicates. Notice how this post is asking how to create variables, not how to access fields via reflection. Of course, it's not like there isn't any duplicates out there on how to access a field via reflection. If you actually thought that was what the question was asking, you could have just changed the duplicate target. – Servy Sep 25 '18 at 21:07

2 Answers2

4

In an ideal world, you never number variables and just use an array (or some other collection). So you would have:

for (int i=0;i<5;i++) 
{
    num[i] = i;
}

Which requires your list of variables to be instead one variable that is indexable (like an array)

int[] num = new int[5];

The only way to access a variable in C# from a string is with reflection (which is a fairly advanced concept, easy to get wrong, and not very efficient). That being said, you'd do something like:

Type thisClass = this.GetType(); //Even better, typeof(WhateverClassThisIs);
for (int i=1;i<5;i++) 
{
    FieldInfo field = thisClass.GetField($"num{i}");
    field.SetValue(this, i);
}

Note that this only works if num1 etc. are existing class members (it does not create them) and not local to the function. If you have local variables, you are basically out of luck.

BradleyDotNET
  • 60,462
  • 10
  • 96
  • 117
  • 4
    just to be clear, current example with reflection provide a way to create a member of type, not a local variable in a some local scope. – George Alexandria Sep 25 '18 at 20:59
  • Correct, if `num1` is local to a method you have no recourse. This only works on class members. – BradleyDotNET Sep 25 '18 at 21:00
  • 1
    The problem is Python is the wild west, C# is more like a city. You have to plan a bit, not just script the world. He should rethink his intent. – Greg Sep 25 '18 at 21:01
  • Reopening a question just to post the same answer as what's covered in the duplicate is abusive and inappropriate. – Servy Sep 25 '18 at 21:01
  • @Servy I scrolled through the answers to the duplicate you linked. I didn't see anything like this (the dupe target covered *creating* dynamic variables, not accessing existing ones) – BradleyDotNET Sep 25 '18 at 21:02
  • @Greg I agree whole-heartedly, that's what I was getting at with the first bit. – BradleyDotNET Sep 25 '18 at 21:03
  • Yeah I agree completely on using collections etc, problem is I'm dealing with a lot of undocumented legacy code and trying to make small improvements here or there without crashing the entire application. – kashmoney Sep 25 '18 at 21:05
  • @BradleyDotNET This question is asking about defining them, and it's also showing locals, not fields. The question doesn't ask at all about accessing existing fields of a class. – Servy Sep 25 '18 at 21:06
  • @kashmoney Seems like a brittle change, not an improvement. – Greg Sep 25 '18 at 21:07
  • @Servy I mean, I can see how the "local" bit is inferred (though the location of the decleration is never shown, I assumed class members on first reading). Reading the question literally it asks for access, not creation ("Is there a way to "). If I misinterpreted the question then I apologize, but I didn't act in bad faith – BradleyDotNET Sep 25 '18 at 21:07
  • @BradleyDotNET You literally showed a block of code declaring a variable, and said that it's a block of code accessing a variable. The block of code is defining a variable, not reading it's value. – Servy Sep 25 '18 at 21:09
  • @Servy On the first block? The variable declaration is just showing a replacement required for the for loop modification. Granted, the first piece of my post is a frame challenge to the original post, the second answers the question as (I believe) it was asked. – BradleyDotNET Sep 25 '18 at 21:11
  • @BradleyDotNET They showed some code that *declares* variables dynamically, and asked how to do the same in C#. They never said anything about accessing variables anywhere in the question. Care to quote the part of the question that says they're looking to access existing variables, rather than to declare variables? – Servy Sep 25 '18 at 21:14
  • @Servy "is there a way to do something like `for (int i=1;i<5;i++) { int f'num{i}' = i; }`" Granted, he's setting it (not getting). Same principles though :) I guess I assumed the `int` in the middle was a mistake re-reading that. – BradleyDotNET Sep 25 '18 at 21:15
  • @BradleyDotNET That's not setting it, that's *declaring* it. Given that the question specifically said that was their intent: "am dealing with code that creates many variables" and they showed code doing just that, I think it's pretty safe to say that they're looking to declare variables, since it's both what they showed and what they said they wanted, rather than saying something about accessing variables and showing accessing a variable. – Servy Sep 25 '18 at 21:18
  • And as mentioned earlier, if you really did think that the question was asking how to set a field via reflection, it's not like that's a novel question. Just change the duplicate (or add another one), if that's really what you think the question is asking. Don't just constantly repeat the same readily accessible content over and over again. – Servy Sep 25 '18 at 21:19
  • @Servy Yeah, I can see where I misunderstood what the code snippet he provided was going for. Sorry for the confusion. – BradleyDotNET Sep 25 '18 at 21:20
  • 1
    @GeorgeAlexandria No, this code is *not* creating a field of a type. It's just setting the value of an already existing field of a type. You can't use reflection to create a field for a type. – Servy Sep 25 '18 at 21:21
  • @Serv, yes, the current code doesn't create a field, my apologies, and you cannot create a field for existing type, but you can do that for a runtime generated type using System.Reflection.Emit API, for example [TypeBuilder](https://learn.microsoft.com/en-us/dotnet/api/system.reflection.emit.typebuilder?view=netframework-4.7.2) – George Alexandria Sep 25 '18 at 21:53
0

This is an example of String Interpolation. Something like $"num{i}" should work for you

2br-2b
  • 395
  • 2
  • 5
  • 13