我正在尝试实现三层深度数据结构。这很容易做到,直到你添加了能够在孩子和/或田地周围移动的要求,然后它变成了一场噩梦。
父母(索引,身份证) - >儿童(指数) - >字段(索引,字符串)
例如,数据可能如下所示:
现在我可以通过为Parent和Field创建包含ArrayList和String的结构,以及只为子类的Arraylist实现这一点,但是当我需要反转Field1和Field2时,它变得困难且昂贵。
在C ++这样的语言中,这一切似乎很容易,因为我可以将所有字段转储到一个巨大的数据块中,然后使用指针来引用字段所在的位置......然后,如果我想切换字段,孩子或父母,我只需要改变指针,它便宜。
有没有人在C#中见过这种数据模式?是否有“标准”方式来实现这一点?
答案 0 :(得分:3)
不要使用结构,使用类。操作只是昂贵的,因为使用结构需要您复制数据,而您可能只是复制对象引用。您对结构的使用可能是由于您使用C ++的经验;在C#中,你想要使用它们的次数较少。
当您在C#中实例化对象时,您“将所有字段转储到一个巨大的数据块中,然后使用指针来引用字段所在的位置”。这就是new
运算符的作用:它在堆上分配对象并为您提供指针。没有必要明确地实现这样的事情。
很难在C#中明确地微观管理内存,但如果你不再尝试这样做,那么我认为你会发现你的生活变得更加轻松。如果你真的想管理内存,请回到C ++。
答案 1 :(得分:2)
为什么不简单地将其组织为对象层次结构?
public class Block
{
public List<Child> Children { get; set; }
public string Name { get; set; }
}
public class Child
{
public List<Field> Fields { get; set; }
}
public class Field
{
public List<string> FieldNames { get; set; }
}
然后,您只需添加对列表的新引用,或者您可以简单地修剪引用或对列表进行排序,如果您需要重新排列内容。我错过了什么吗?
答案 2 :(得分:0)
交换两个引用实际上相当便宜,实际上即使你想从一个孩子中删除一个项目并将其添加到另一个孩子,它仍然几乎总是足够便宜。
using System.Collections.Generic;
public class Block : List<Child> {
public int ID { get; set; }
public Block(int id) {
this.ID = id;
}
}
public class Child : List<string> {
}
public class Test {
public static void Main() {
List<Block> blocks = new List<Block>() {
new Block(1) {
new Child() {
"Hello",
"World"
},
new Child() {
"One",
"Two",
"Three"
}
},
new Block(2) {
new Child()
}
};
string temp = blocks[0][0][0];
blocks[0][0][0] = blocks[0][0][1];
blocks[0][0][1] = temp;
}
}
答案 3 :(得分:0)
在管理字段时看不到任何问题。将它们推入列表中,并且在您希望更改序列时,只需交换该列表中的对象即可。如果从性能角度来看这很昂贵,那么您可以使用字典而不是列表,而不是像字段索引和值字段本身那样使用字典,如果需要,只需交换整数。