Reputation: 7128
I have multiple instances of a class that I would like to track within an array that holds this type of class that I do not control. To do so I have created a List<MyClass>
that I then compare to each value in the MyClass[]
that I do not control.
I then print out the name of the class references with the C#6.0 operator nameOf
. To my surprise (well its obvious now why) when I go to print the name of the class references when checking it from the List
the loop variable name is printed instead of the class reference it references.
Is there a way to print the name of a variable that is referenced by another variable?
(Also what is the proper jargon to use for this question, I feel like I butchered it?)
Here is an example of the issue using Control
Control x = new Control();
Control y = new Control();
Control z = new Control();
var controlArr = new Control[] { x, y, z };
var controlList = new List<Control>() { x, y, z };
for (int i = 0; i < controlArr.Length; i++)
{
Control anArrControl = controlArr[i];
foreach (var aListControl in controlList)
if (anArrControl == aListControl)
Console.Out.WriteLine("Control[" + i + "]: " + nameof(aListControl));
}
This code will print
Control[0]: aListControl
Control[1]: aListControl
Control[2]: aListControl
Instead of
Control[0]: x
Control[1]: y
Control[2]: z
EDIT: This example is simple in that if the Control[]
does not contain a reference in the List<Control>
nothing will be printed. In my actual application I take care of this. I simply put the example code to demonstrate what I mean when I asked the question, I didn't feel as if I worded it properly.
Upvotes: 2
Views: 418
Reputation: 15405
On MSDN you find a reference of use cases that motivated the creation of the nameof function. The name of a reference is not defined at compile time. Given
var a = new object();
var b = a;
var array = new [] {a, b}
What should nameof(array[1])
return ? It is the same referenced object.
Therefore you have to think of another workaround to achieve your goal. Perhaps a Dictionary might help you. Like
Control x = new Control();
Control y = new Control();
Control z = new Control();
var references = new Dictionary<Control, string> {
{ x, "x" }, { y, "y" }, {z, "z"}
};
var controlArr = new Control[] { x, y, z };
var controlList = new List<Control>() { x, y, z };
for (int i = 0; i < controlArr.Length; i++)
{
Control anArrControl = controlArr[i];
foreach (var aListControl in controlList)
if (anArrControl == aListControl)
Console.Out.WriteLine("Control[" + i + "]: " + references[aListControl]);
}
Upvotes: 3
Reputation: 172200
Nope, that won't work, since controlList does not contain x, y and z - it contains the controls that x, y and z refered to at the time of assignment.
There are two alternatives that you might want to consider:
Store the control and its variable name in a List<Tuple<Control, String>>
:
var controlList = new[] {
Tuple.Create(x, nameof(x)),
Tuple.Create(y, nameof(y)),
Tuple.Create(z, nameof(z))
}.ToList();
Obviously, your comparison then needs to be changed to anArrControl == aListControl.Item1
.
Some classes (such as WinForm's Control
) have a Name
property. Maybe that name suits your purpose as well?
Upvotes: 2