c# - 为什么在枚举对象上设置属性不起作用?

标签 c# ienumerable

我对 C# 了解很多,但这个问题难倒了我,Google 也无济于事。

我有一个 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<> 或数组?

谢谢! -迈克

最佳答案

当您调用 First() 时,它会枚举这段代码的结果:

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

请注意,Select 是一个惰性枚举器,这意味着它仅在您向其中请求某个项目时才执行选择(并且每次您请求时都执行)。结果不会存储在任何地方,因此当您调用 items.First() 时,您会得到一个新的 SubItem 实例。当您随后将项目传递给 Write 时,它​​会获得一大堆新的 SubItem 实例 - 不是您之前获得的实例。

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

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

关于c# - 为什么在枚举对象上设置属性不起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/317527/

相关文章:

c# - 抑制 Windows Mobile 6 中的操作系统消息

c# - 如何创建 IEnumerable.ToString

C#:当字段不为空时返回 IEnumerable?

c# - 具有底层字节类型的枚举在开关中失败

C# 转换回 var 类型?

c# - 我不能在 .ascx 上使用 IEnumerable() 吗?

c# - C# LINQ 方法链中赋值的编译器警告?

vb.net - 有没有一种方法可以检查是否使用For Each循环访问IEnumerable?

c# - 通过查看每个对象自己的路径对多个对象集合进行排序

c# - 如何在客户端使用自定义类型对象