如何修改我传入的对象集合上的字段

时间:2011-10-27 05:36:28

标签: c# foreach mutable ref

我正在尝试做以下事情......(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;
}

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

3 个答案:

答案 0 :(得分:3)

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

答案 1 :(得分: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();

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

答案 2 :(得分:0)

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

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

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

  • 你传递的是哪个集合(List,Set)?
  • 如果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;
        }
    }
}