我对 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/