繁体   English   中英

更改可枚举集合中的对象

[英]Change objects in an enumerable collection

我有一个不能通过(通过索引)进行迭代的集合,但是它确实实现了IEnumerable

枚举时是否可以替换该集合中的对象? 我知道这在foreach循环中是不可能的,但是似乎很想做。

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

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

  1. 看来很浪费
  2. 更重要的是,它失去了整个结构。

出于示例目的:

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[]在此处播放。假设基础结构是未知的/高度复杂。

我怎样才能做到这一点?

正如payo所说,您的陈述相互冲突。 您无法通过IEnumerable进行迭代,但是您处于foreach循环(即迭代)中。 IEnumerable几乎说您可以通过集合进行枚举。 但是,这是我对您的问题的投入:

枚举集合时,您尝试更改枚举通过的数据时会受到限制。 而且您绝对不能删除任何内容。 部分原因是由于更改枚举的可能性。

一种可能的方法是创建项目列表,在列表中进行枚举,然后将所需内容放入列表中。 然后假设它们公开了.Add(IEnumerable list),然后重新加载IEnumerable。

在一种情况下,我有一些要从IEnumerable中删除的项目,因此我进行了一次foreach,跟踪了要删除的每个对象,然后在枚举之后,对保存的每个对象进行了删除。

如今,使用linq,您可以更轻松地执行一些操作,例如删除对象,如果您可以对所需的内容进行明确定义的查询(保留不想要的内容),然后对IQueriable结果集进行处理。

一句话: 链表

您没有说过是否需要实现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++;
    }
}

按照您的描述方式,我无法想到轻松替换这些项目。
您声称:

  • 没有添加/删除方法-没有简单的更改方法
  • 基础集合的格式是未知的-使反射选项更难使用
  • 您只有暴露给您的枚举数-这意味着您只能进行

可能的解决方案是:

  • 反映基础类型,了解其格式并通过反思来更改所需的任何内容
  • 如果可能的话,请使用深度复制(如已建议)。 深层复制,如果您不熟悉该术语,则意味着您将根据需要使用您要放置的对象的并行值(而不是被替换的对象)的并行值,根据需要进行深度递归更新要替换的对象及其属性。 。 当然,如果您只关心引用而不是每个对象的数据/值,则此解决方案将行不通。 有数十个线程解释了如何在SO上使用深度复制,因此找到示例应该没有问题

原始收藏有哪些突变方法? 如果它支持物品的删除或替换,它通过什么方式识别要删除或替换的物品?

某些实现IEnumerableIEnumerable<T>将允许枚举合理地工作,即使基础集合被修改(整个枚举中集合中的项目也将被精确返回,而那些在枚举中的集合中的项目将被完全返回)。将最多返回一次,而在枚举期间根本不是集合的那些将根本不会返回)。 如果您使用的类的行为是这样,那就太好了。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM