【问题标题】:Iterating over an array using index and assigning values depending on index使用索引迭代数组并根据索引分配值
【发布时间】:2012-10-26 07:25:46
【问题描述】:

我今天早些时候面对this problem,由于找不到满意的解决方案,我决定改变我的类设计,并拥有单独的属性,例如标签1、标签2、标签3等。

我的主要问题是我需要将网格绑定到包含其他属性列表的对象,并且我需要将列表中的每个项目显示为单独的列,这是我无法做到的。因此,我诉诸单独声明变量。 Original question is here...

现在,我面临着每个程序员在某个时间点可能遇到的最常见的设计问题之一。这是演示它的代码,

for (int i = 0; i < tags.Length; ++i) // Length not known here.
{
    if(i==0){
        tag1 = tags[0];
    } 
    else if(i == 1){
        tag2 = tags[1];
    }
    else if(i == 2){
        tag3 = tags[2];
    }
    ....
}

这里tags是一个字符串数组。

我想知道是否有更优雅的方法来做到这一点。另一件需要注意的是,这个循环的效率随着它的进行而降低,因为随着更多的迭代它必须检查更多的条件。如果我们可以在条件变为 true 一次 后将其删除,那么它将加快每次迭代,因为我们知道每个条件在所有迭代中只会变为 true 一次

【问题讨论】:

  • 出于好奇,为什么需要将tags 的元素分配给各个变量?数组的重点是防止我们需要连续序列的单个变量...
  • 詹姆斯说了什么。好像这是在倒退。
  • 那是什么tags.Length[]???它似乎无效。
  • @James,我在文本框中以逗号分隔值的形式从用户那里收到此信息,然后我继续使用 string.Split(',') 拆分字符串以获取该数组。跨度>
  • 如果您想将它们分配给更有意义的变量,那很好,但您应该按照@MiguelAngelo 的建议直接执行。

标签: c# c#-4.0 design-patterns


【解决方案1】:

将关于DataGridView 的答案和使用ComponentModel 移动到正确的问题: Displaying a list of object containing a list in a grid view

简报

DataGridView 控件支持ComponentModel 命名空间,因此您可以创建看似具有不存在属性的类。这与PropertyGrid 使用的机制相同。

示例代码在该问题的这个答案中: https://stackoverflow.com/a/13078735/195417

老答案

这是我之前的回答,当时我没有意识到真正的问题是关于 DataGridView 控件。


这和直接设置值不一样吗:

this.tag1 = tags[0];
this.tag2 = tags[1];
this.tag3 = tags[2];

编辑:正如你所说,你不知道需要多少个变量,那么你只需要一个,那就是一个列表:

var list = new List<string>();
for (int i = 0; i < tags.Length; ++i)
{
    list.add(tags[i]);
}

如果您只想复制所有值,您甚至可以这样做:

var list = new List<string>(tags);

告诉我这是否是你想要的......也许我误解了这个问题。

【讨论】:

  • 好的,抱歉!我不应该这么说……也许这家伙还在学习。
  • @MiguelAngelo 感谢您的厚颜无耻的评论,确实有助于增强我的信心。不,我不是初学者。如果您愿意回答更新后的问题,我很想离开这里,哭着入睡……
  • @MiguelAngelo 您正确理解了错误的原始问题,但未能理解我更正的问题。我的主要问题是我需要将网格绑定到包含其他属性列表的对象,并且我需要将列表中的每个项目显示为单独的列。因此,我诉诸单独声明变量。我应该明确提到我的要求,我的错误。这是原始问题.. stackoverflow.com/questions/13064156/…
  • 我会在一分钟内改变我的答案!我明白了……对不起,我一时失明了。
  • 它是什么控件?一个 DataGridView?
【解决方案2】:

整个循环毫无意义。但是除非标签数组的长度总是相同的,否则你必须确保不要越界......

if(tags.Length >= 1) this.tag1 = tags[0];
if(tags.Length >= 2) this.tag2 = tags[1];
if(tags.Length >= 3) this.tag3 = tags[2];
if(tags.Length >= 4) this.tag4 = tags[3];
if(tags.Length >= 5) this.tag5 = tags[4];

...无论你有多少 this.tag#,都以此类推。

【讨论】:

  • 这会有点用。但是我仍然不知道我必须事先声明多少变量。
  • 好吧,'this' 指的是什么?在什么时候是tag1。标签2。 tag3 声明(而不是分配给)您是否希望动态创建底层类,以便 tagX 字段的数量发生变化?还是会有一组可以使用的 tagX 字段。
  • 如果你希望你的底层类这次有 tag1、tag2、tag3 属性,但下一次 tag1、tag2、tag3、tag4 属性不修改你的源代码,并且不重新编译你需要这样的东西:stackoverflow.com/q/2698619/391656。但是,如果您的班级总是有 tag1 到 tag9,那么您就知道有多少个变量。你没有改变声明的数字,只需要控制你分配的数量。
【解决方案3】:

这本质上是一样的:

for(int index = 0; index < tags.Length[]; index++){
    switch(index){
        case 0:
            tag1 = tags[0];
            break;
            // And so on
    }
}

【讨论】:

  • 不幸的是,这并没有更好...好吧,稍微更好,因为它可能在幕后使用跳转表而不是 if-ladder,但当使用可以像@MiguelAngelo 建议的那样简单地做,或者只是使用数组
  • 是的,我知道,但我不知道他是否必须使用循环(出于某种原因)
  • 不分配变量,这是他问题的主旨。他仍然可以有循环,但是通过循环将变量分配给每个索引的内容充其量是非常次优的。
  • 再for(int index = 0; index
猜你喜欢
  • 1970-01-01
  • 2012-02-11
  • 2021-04-17
  • 1970-01-01
  • 2014-11-13
  • 1970-01-01
  • 2019-03-06
  • 1970-01-01
  • 2022-11-07
相关资源
最近更新 更多