3

我正在尝试执行以下操作...(Foo 是一个类)

void Main() 
{
    var foos = ...
    DoSomeWork(foos);
    // I want all foos to have Bar set to 42
}

public static void DoSomeWork(IEnumberable<Foo> foos) 
{
    foreach (var foo in foos)
    {
        foo.Bar = 42;
    }
}

class Foo 
{
    String blahblah;
    Int32 Bar;
}

但是所有的 foo 都有其原始值。如何在 ref 参数上更改它们?

4

3 回答 3

3

由于您不使用ToListor之类的方法强制执行 LINQ 查询ToArray,因此每次枚举查询时它都会重新执行一次。您需要使用该ToList方法缓存查询结果,然后将该列表传递给该DoSomeWork方法。

于 2011-10-27T05:52:06.377 回答
2

这可能foos是一个生成IEnumerable. 例子:

IEnumerable<Foo> GetFoos()
{
  yield return new Foo {};
  yield return new Foo {};
  yield return new Foo {};
}

var foos = GetFoos();

您永远不能改变正在生成的值,因为每次迭代时它们都会重新创建foos

现在,如果您按照@YuriyRozhovetskiy 的建议执行以下操作,它将起作用。

var foos = GetFoos().ToList();

现在我们可以愉快地变异了:)

于 2011-10-27T05:51:05.993 回答
0

这很奇怪,它应该适用于引用类型(类),它不会为值类型(结构)编译。

首先,你不需要将 ref IEnumerable 传递给 DoSomeWork,因为你不想改变集合对象,只修改里面的元素。

我试图重现你的情况,但它工作正常,代码如下。你能提供更多细节吗?

  • 你正在传递什么集合(列表,集合)?
  • 如果 Bar 是财产 - 它是如何实现的?
  • Foo 是引用类型(类)吗?

工作代码:

class Foo
{
    public Foo(int bar, int baz)
    {
        Bar = bar;
        Baz = baz;
    }
    public int Bar { get; set; }
    public int Baz;
}

class Program
{
    static void Main(string[] args)
    {
        var foos = new List<Foo>(new[]
        {
            new Foo(1, 2),
            new Foo(3, 4),
            new Foo(5, 6)
        });
        DoSomeWork(foos);
    }

    private static void DoSomeWork(IEnumerable<Foo> foos)
    {
        foreach (var foo in foos)
        {
            foo.Bar = 42;
            foo.Baz = 42;
        }
    }
}
于 2011-10-27T05:48:58.920 回答