我知道很多关于C#但是这一个是绊倒我,谷歌并没有帮助。

我有对象的IEnumerable范围。我想设置的第一个属性。我这样做,但是当我修改后枚举对象的范围,我没有看到我的变化。

这里的问题的一个很好的例子:

    public static void GenericCollectionModifier()
    {
        // 1, 2, 3, 4... 10
        var range = Enumerable.Range(1, 10);

        // Convert range into SubItem classes
        var items = range.Select(i => new SubItem() {Name = "foo", MagicNumber = i});

        Write(items);  // Expect to output 1,2,3,4,5,6,7,8,9,10

        // Make a change
        items.First().MagicNumber = 42;

        Write(items);  // Expect to output 42,2,3,4,5,6,7,8,9,10
        // Actual output: 1,2,3,4,5,6,7,8,9,10
    }

    public static void Write(IEnumerable<SubItem> items)
    {
        Console.WriteLine(string.Join(", ", items.Select(item => item.MagicNumber.ToString()).ToArray()));
    }

    public class SubItem
    {
       public string Name;
       public int MagicNumber;
    }

什么方面的C#停止输出我的“MagicNumber = 42”的变化?有没有一种方法我可以让我改变的“大棒”,而不做一些时髦转换为List <>或数组?

谢谢! -Mike

有帮助吗?

解决方案

当调用首先()它枚举在该位的代码的结果:

Select(i => new SubItem() {Name = "foo", MagicNumber = i});

请注意选择是一个懒惰的枚举,这意味着只有当你要求它从一个项目做的选择(和做它的每一个的时候,你问吧)。结果不存储,所以当你调用items.First()你会得到一个新的SubItem实例。当你再传给项目撰写,它获得新SubItem实例一大堆 - 不是你以前有一个

如果你想存储你的选择的结果,修改它,你需要做的是这样的:

var items = range.Select(i => new SubItem() {Name = "foo", MagicNumber = i}).ToList();

其他提示

我怀疑一些事情的背景。最可能是由于这样的事实,所述IEnumerables只能使用一次迭代。

是否如果添加了一个分配给“项目”工作时“ToList()”,来电后选择()?

我能想到的唯一的事情就是items.First()通过分项的副本的你,而不是引用,所以当你设置的变化没有得到贯彻。

我必须假设它是与IQueryable的只能够进行一次迭代。你可能想尝试改变这一点:

// Convert range into SubItem classes
var items = range.Select(i => new SubItem() {Name = "foo", MagicNumber = i});

// Convert range into SubItem classes
var items = range.Select(i => new SubItem() {Name = "foo", MagicNumber = i}).ToList();

和查看是否有任何不同的结果。

您不能/不应该通过枚举修改的集合。我很惊讶,这并不抛出异常。

。首先()是一种方法,而不是一个属性。它在你的可枚举的第一个位置返回对象的新实例。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top