使用引用另一个变量的nameOf打印变量名称?

时间:2016-10-19 20:19:47

标签: c# c#-6.0

我有一个类的多个实例,我想在一个数组中跟踪,该数组包含我无法控制的这种类。为此,我创建了一个List<MyClass>,然后我将其与我无法控制的MyClass[]中的每个值进行比较。

然后我用C#6.0运算符nameOf打印出类引用的名称。令我惊讶的是(现在很明显为什么)当我从List检查它时打印类引用的名称时,打印循环变量名称而不是它引用的类引用。

有没有办法打印另一个变量引用的变量名称?

还有什么是用于这个问题的正确行话,我觉得我已经宰了它?

以下是使用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));
}

此代码将打印

Control[0]: aListControl 
Control[1]: aListControl 
Control[2]: aListControl 

而不是

Control[0]: x
Control[1]: y
Control[2]: z

编辑:此示例很简单,如果Control[]List<Control>不包含引用,则不会打印任何内容。在我的实际应用中,我会照顾这个。我只是用示例代码来说明当我提出这个问题时我的意思,我并不觉得我说得好。

2 个答案:

答案 0 :(得分:3)

MSDN上,您可以找到促使创建功能名称的用例参考。引用的名称未在编译时定义。给定

 var a = new object();
 var b = a;
 var array = new [] {a, b}

nameof(array[1])应该返回什么?它是相同的引用对象。

因此,您必须考虑另一种解决方法来实现您的目标。也许词典可能会帮助你。像

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

答案 1 :(得分:2)

不,这不会起作用,因为controlList不包含x,y和z - 它包含x,y和z在赋值时所引用的控件。

您可能需要考虑两种选择:

  1. 将控件及其变量名称存储在List<Tuple<Control, String>>中:

    var controlList = new[] {
        Tuple.Create(x, nameof(x)),
        Tuple.Create(y, nameof(y)),
        Tuple.Create(z, nameof(z))
    }.ToList();
    

    显然,您的比较需要更改为anArrControl == aListControl.Item1

  2. 某些类(例如WinForm's Control)具有Name属性。也许这个名字也适合你的目的?