【问题标题】:How can I compose variables names through loop in C#?如何在 C# 中通过循环组合变量名称?
【发布时间】:2014-01-03 16:35:40
【问题描述】:

我重写了这个问题,因为不是每个人都理解。希望没关系,这是同样的主要问题。非常抱歉

我有一个带有 15 个进度条的 winform,名为:“baraClasa1”、“baraClasa2”、“baraClasa3”...“baraClasa15”。我必须从一些数据库记录中将 .VALUE 属性(如 int)分配给所有这些属性。 (记录访问不同时间段的不同值) 我在想也许可以通过执行以下操作来使用循环将 .Value 属性分配给所有这些属性:

for(int i=0; i<value; i++)
{
   "baraClasa+i".Value = 20 + i;  
}

是否可以这样组合变量的名称?

我对字典和列表了解不多,但我正在研究。如果没有任何效果,我只会做丑陋的事情:

int value = 20;
baraClasa1 = value;
baraClasa2 = value +1;....

感谢大家的帮助

【问题讨论】:

  • 我不认为 c# 可以创建动态变量,最好的办法是使用集合或数组。
  • 除非variable 实际上是一个数组或其他索引集合,那么[] 是没有意义的。
  • 重新思考您的设计。数组是要走的路。变量名完全是为了给开发者一个关于变量用途的提示。程序逻辑不应依赖于变量名。
  • 字典会让你接近相同的结果。调用元素将是 dict["variableName"] msdn.microsoft.com/en-us/library/xfhwa508(v=vs.110).aspx
  • @FelixCastor:虽然知道在这种情况下"variableName" 实际上(至少不是自动)不是变量名。

标签: c# winforms loops variables


【解决方案1】:

你必须做一点反思。

    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
    }

无需对更新的问题使用反射。控件集合具有内置的查找功能,用于通过名称字符串获取控件。

 for (int i = 0; i < 6; i++)
 {
   ProgressBar bar = (ProgressBar)this.Controls["baraClasa" + i.ToString()];
   bar.Value =  50;
 } 

【讨论】:

  • 抛开性能和其他方面的考虑,这仅适用于字段,不适用于局部变量。
  • 正确。他的最后一次编辑说它们是控制名称,所以这可以解决问题。我同意重新设计会是更好的方法,但有时这不是一种选择。
  • 我相信在这个例子中我只能改变控件的.Text属性?
  • 实际上,对于您更新的问题,您甚至不必使用反射。您可以通过控件集合中的字符串值找到它们。我会更新我的答案。
  • 今天晚些时候我会检查一下,告诉你进展如何
【解决方案2】:

这是一个设计问题。为常用的项目(例如进度条)创建一个集合,并遍历该集合以对它们执行操作。

如果这些是进度条,您可能希望使用event-driven design (another link) 来更新它们的进度,这意味着每次进度条取得一些进展时,进度事件将仅向该进度条发送更新bar,而不是遍历整个列表。

在重构代码之前,您可能需要阅读introduction to event driven programming in C#

【讨论】:

  • 值取自前几天的数据库,具体取决于选择的时间。我能想到的事件驱动设计不多
  • 仍然,您应该创建一个集合以批量执行操作(您是对的,考虑到您的情况,事件驱动设计不是必需的)。您可以在每个选择中重复使用该集合,因此您不必重新创建它。如果每次发现集合都不一样,那么事件驱动的设计终究还是适用的。
【解决方案3】:

在 C# 中确实不可能像您尝试做的那样以动态方式引用局部变量。相反,您在 C# 中所做的是将值存储在字典中,其中可以以动态方式生成键。

例如,假设您的所有变量 1、变量 2、...变量 N 的类型均为 int。而不是

int variable1 = 0;
int variable2 = 0;
...
int variableN = 0;

您可以改为执行以下操作

Dictionary<string, int> map = new Dictionary<string, int>();
for (int i = 0;  i < N; i++) {
  map[i.ToString()] = 0;
}

如果值是一个固定数字并且总是线性进行,那么使用数组而不是字典可能是有意义的

int[] array = new int[N];
for (int i = 0; i < N; i++) {
  array[i] = 0;
}

【讨论】:

    【解决方案4】:

    你不能那样做。你需要一个数组。每次你发现自己有一个变量2,你就需要一个数组。你可能还不知道,但你知道。

    【讨论】:

      【解决方案5】:

      不,你不能在 C# 中做到这一点,这在语法上是不可能的。但是,如果您想要访问具有不同名称的表单控件,您可以执行以下操作:

      for(int i=0; i<20; i++)
      {
        var name = "variable" + i;
        this.Controls[name].Text = "etc..." // here you can access your control
      }
      

      【讨论】:

      • it's syntactically impossible 肯定不是。这很困难,而且几乎总是一个坏主意,但肯定不是不可能的。如果变量是实例字段,你可以通过反射来完成,你可以创建一个表达式树来处理大多数情况,如果最坏的情况发生,你总是可以使用 unsafe 来做......几乎任何事情。
      • @Servy,真的吗?你认为反射是可能的吗?我不知道如何通过反射来做到这一点
      • 这将取决于具体情况。我不确定你是否可以通过反射改变本地人。不过,您可以通过字符串名称轻松访问当前实例(或任何实例)字段。
      • @Servy 是的,也许你是对的,我们可以动态创建变量名,然后在运行时访问当前程序集的字段。实际上值得一试:D
      • 正如我所说,这几乎肯定不是解决这个问题的正确方法,我认为按照这些思路的答案是有害的,但是说这样做是不可能的是不正确的,因为肯定不是,只是不受欢迎
      【解决方案6】:

      如果您想为对象命名,请使用字典:

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

      然后您可以通过以下方式访问它们,例如:

      myDict["MyPattern1"]
      

      但是,我建议您最好使用 List 或数组之类的集合。

      【讨论】:

        【解决方案7】:

        数组、列表、字典、哈希映射...一般来说,你会在这里使用集合。例如,如果您有一个字典,那么它由键/值对组成。所以字典可能看起来像这样:

        var variable = new Dictionary<int, string>();
        

        int 是任何给定条目的键,string 是值。您可以这样分配值:

        for(int i = 0; i < value; i++)
            variable.Add(i, assign[i]);
        

        当然,因为i 在这种情况下只是一个递增的整数(除非您有其他键?),所以它的工作原理与列表上的索引器一样。像这样的:

        var variable = new List<string>();
        for (int i = 0; i < value; i++)
            variable.Add(assign[i]);
        

        在这两种情况下,您稍后都可以通过引用其键(在字典中)或其索引(在列表或任何数组中)来访问分配的值:

        var someOtherVariable = variable[x];
        

        其中x 是存在于字典键或数组大小中的整数值。

        【讨论】:

          【解决方案8】:

          如果你可以将所有变量的名称放在一个数组中,例如'variable',并且它们是唯一的,你可以尝试使用字典:

              Dictionary<object, object> dictionary = new Dictionary<string, object>();
              for(int i=0; i<value; i++)
              {
                   dictionary.Add(variable[i], assign[i]);
              }
          

          【讨论】:

            猜你喜欢
            • 2014-06-09
            • 1970-01-01
            • 2011-07-14
            • 2018-12-07
            • 1970-01-01
            • 2012-01-05
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多