1

我使用以下代码单步执行IEnumerable

IEnumerable<Thing> things = ...;
foreach (Thing thing in things)
  thing = method(thing);

编译器不同意它,因为我指是迭代变量。当然,我打算改为影响列表中的基础对象。我怎么做?

现在,我使用数字迭代解决了这个问题,但那里有两个问题。一方面,恕我直言,编码不好。除此之外,它还需要我将我的东西IEnumerable更改为IList(或者我什至应该使用List吗?!),当事情变大时,它咬住我的下背部。

//List<Thing> things = ...;
IList<Thing> things = ...;
for (int i = 0; i < things.Count(); i++)
  things[i] = method(things[i]);
4

5 回答 5

4

您可以使用 Linq 投影序列:

 var transformedThings = things.Select(t => method(t));
于 2013-03-18T12:15:16.947 回答
2

如果要在所有元素上运行该方法,为什么不转换整个集合:

public IEnumerable<Thing> TransformThings(IEnumerable<Thing> input)
{
    foreach (var thing in input)
        yield return method(thing);
}

你可以像这样使用它:

var transformedThings = TransformThings(things);

这将在您遍历集合时转换每个元素,这意味着您不必将整个集合枚举到内存中。

编辑

更简单:

var transformedThings = things.Select(thing => method(thing));
于 2013-03-18T12:11:53.417 回答
1

在迭代列表中的项目时,您不能更改引用,因为它限制在枚举器中,但您可以更改项目中的对象...。

使用功能强大的 LINQ 或只是克隆您的列表,如 ToList() 或 ToArray()。

于 2013-03-18T12:24:13.100 回答
1

使用某些集合可以轻松完成项目替换,例如数组或List<T>(如您所述)使用for循环(不是foreach)。

无法使用语句替换对象。foreach

如果你真的想使用IEnumerable<T>接口,有两种选择:

  1. 变换 s 的序列ThingIEnumerable<T>.Select()方法)。在这种情况下,Thing 不修改源序列和源实例。

    例如:

    var newThings = things.Select(t => new Thing(/* pass different values using original t instance */));
    
  2. 更新每个实例的状态:

    class Thing
    {
        public void UpdateState(/* parameters */)
        {
            // Update field/property values, etc.
        }
    }
    
    ...        
    
    foreach (var thing in things)
        thing.UpdateState(/* new values */);
    
于 2013-03-18T12:21:00.557 回答
0

如果IEnumerable将保持相同的长度,我将使用ToArray()并使用循环进行迭代for

例如:

char[] chars = "somestring".ToArray();
for (int i = 0; i < chars.Length; i++)
{
  chars[i] = SomeMethod();
}

用于修改集合中的某些内容。

Thing[] things = ...;
for (int i = 0; i < things .Length; i++)
{
  AddOne(ref things[i]);
}

public void AddOne(ref Thing t)
{
  t.Foo += 1;
}
于 2013-03-18T12:18:40.197 回答