我有一个无法通过(通过索引)迭代的集合,但它确实实现了IEnumerable
。
有没有办法在枚举时替换该集合中的对象?我知道在foreach
循环中这是不可能的,但想要这样做似乎是合理的。
我甚至考虑使用C#的指针,但那些不适用于托管类型。
我知道我可以使用所有数据填充数组,然后以这种方式进行编辑,但
例如:
public void Example(object a,object b, object c)
{
object[] ex = {a,b,c};
object d = new MyCustomType();
}
如果不使用任何索引器,我如何才能ex
暂停{a,d,c}
?假设我可以访问ex
的唯一方法是通过枚举器。类型中没有Add
或AddAt
方法(由object[]
在此处播放。假设底层结构未知/非常复杂。
我该怎么做?
答案 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)
你描述它的方式,我无法想到轻易更换物品 你声称:
可能的解决方案是:
答案 3 :(得分:0)
原始系列有哪些突变方法?如果它支持删除或更换物品,它以何种方式识别要移除或更换的物品?
实现IEnumerable
或IEnumerable<T>
的某些类将允许枚举即使在修改基础集合时也能合理地工作(整个枚举中集合中的项目将返回正确的项目,那些是在部分枚举的集合中,最多只返回一次,而在枚举期间根本不返回的集合将不会被退回。如果您使用的课程表现得那么好,那就很好。
否则,您最好的选择可能是在枚举类时构建“编辑”列表,然后在枚举完成后应用这些编辑。