更改不可相关集合中的对象

时间:2012-06-05 18:38:24

标签: c# collections ienumerable

我有一个无法通过(通过索引)迭代的集合,但它确实实现了IEnumerable

有没有办法在枚举时替换该集合中的对象?我知道在foreach循环中这是不可能的,但想要这样做似乎是合理的。

我甚至考虑使用C#的指针,但那些不适用于托管类型。

我知道我可以使用所有数据填充数组,然后以这种方式进行编辑,但

  1. 这看起来非常浪费
  2. 更重要的是,它失去了整个结构。
  3. 例如:

    public void Example(object a,object b, object c)
    {
        object[] ex = {a,b,c};
        object d = new MyCustomType();
    }
    

    如果不使用任何索引器,我如何才能ex暂停{a,d,c}?假设我可以访问ex的唯一方法是通过枚举器。类型中没有AddAddAt方法(由object[]在此处播放。假设底层结构未知/非常复杂。

    我该怎么做?

4 个答案:

答案 0 :(得分:1)

正如payo所说,你的陈述相互冲突。您无法遍历IEnumerable,但是您处于foreach循环中,这是迭代。 IEnumerable几乎说你可以枚举整个集合。但这是我对你的问题的意见:

通过集合进行枚举时,您将无限制地尝试更改您要枚举的数据。你绝对不能删除任何东西。在某种程度上,这是由于有可能改变枚举。

一种可能的方法是创建一个项目列表,通过列表枚举并将您想要的内容放入列表中。然后重新加载IEnumerable,假设它们公开.Add(IEnumerable list)。

在某种情况下,我有一些我想从IEnumerable中删除的项目,所以我做了一个foreach,跟踪了我想删除的每个对象,然后在枚举后我删除了我保存的每个对象。

现在,使用linq,你可以更容易地做一些事情,比如删除对象,如果你可以用一个很好的定义你想要的查询(省略你不想要的东西),然后对着IQueriable结果集进行处理。

答案 1 :(得分:0)

总之:链接列表

你还没有说过你是否需要来实现IEnumerable(例如用于LINQ),或者你对你所引用的神秘集合有多少控制权。但是,如果你的问题是根本性的,“我怎样才能在C#中迭代它时修改某种类型的集合?”......好吧,这就是链表实际上是好的(而且效率极高)。例如:

var intList = new LinkedList<int>(new []{ 1, 4, 5, 7, 12 });
var node = intList.First;
do {
    // do stuff with node
    if (node.Value < 3){
        node.List.AddAfter(node, node.Value + 1);
    } else if(node.Value == 7) {
        var prevNode = node.Previous;
        node.List.Remove(node);
        node = prevNode;
    }

    // Get the next node
    node = node.Next;
} while (node != null);

我不是说您应该将源代码收集复制到链接列表中,因为我们没有足够的信息。但也许这可以向您和未来的读者展示链接列表的用途 - 即在没有索引访问器的情况下进行枚举时进行修改。

请注意,如果您提到的这个集合完全是假设的,那么您提供的信息就没有答案:IEnumerable不需要任何方法来修改“底层集合”。事实上,IEnumerable甚至不需要那里的基础集合。例如,这是一个返回IEnumerable<int>没有底层集合的方法:

public static IEnumerable<int> Range(int minValue, int maxValue) {
    int current = minValue;
    while (current <= maxValue) {
        yield return current;
        current++;
    }
}

答案 2 :(得分:0)

你描述它的方式,我无法想到轻易更换物品 你声称:

  • 没有添加/删除方法 - 没有简单的方法可以更改
  • 底层集合的格式未知 - 使反射选项更难使用
  • 您只有向您公开的调查员 - 这意味着您只能预约

可能的解决方案是:

  • 反映基础类型,了解其格式并通过反思改变您想要的任何内容
  • 如果可能,请使用深层副本,正如我已经建议的那样。深层复制,如果您不熟悉该术语,则意味着您将根据需要更新要替换的对象及其在递归中的属性,并使用要放置的对象的并行值而不是替换的对象值。当然,如果您关心引用而不关心每个对象的数据/值,则此解决方案不起作用。有很多线程解释如何在SO上使用深层复制,所以找到样本不应该有问题

答案 3 :(得分:0)

原始系列有哪些突变方法?如果它支持删除或更换物品,它以何种方式识别要移除或更换的物品?

实现IEnumerableIEnumerable<T>的某些类将允许枚举即使在修改基础集合时也能合理地工作(整个枚举中集合中的项目将返回正确的项目,那些是在部分枚举的集合中,最多只返回一次,而在枚举期间根本不返回的集合将不会被退回。如果您使用的课​​程表现得那么好,那就很好。

否则,您最好的选择可能是在枚举类时构建“编辑”列表,然后在枚举完成后应用这些编辑。