我有一个非常简单的程序,它创建了一堆对象并迭代它们来设置每个对象的Priority
属性.
static void Main(string[] args) { foreach (var obj in ObjectCreator.CreateObjectsWithPriorities()) Console.WriteLine(String.Format("Object #{0} has priority {1}", obj.Id, obj.Priority)); } class ObjectCreator { public static IEnumerableCreateObjectsWithPriorities() { var objs = new[] { 1, 2, 3 }.Select(i => new ObjectWithPriority() { Id = i }); ApplyPriorities(objs); return objs; } static void ApplyPriorities(IEnumerable objs) { foreach (var obj in objs) { obj.Priority = obj.Id * 10; Console.WriteLine(String.Format("Set priority of object #{0} to {1}", obj.Id, obj.Priority)); } } } class ObjectWithPriority { public int Id { get; set; } public int Priority { get; set; } }
我期望IEnumerable
在Main方法中包含具有修改优先级的对象.但是,所有这些都具有默认值0.这是日志:
Set priority of object #1 to 10 Set priority of object #2 to 20 Set priority of object #3 to 30 Object #1 has priority 0 Object #2 has priority 0 Object #3 has priority 0
suche行为的原因是什么?为了让我的优先事项有效,我应该在这里改变什么?
当你这样做:
var objs = new[] { 1, 2, 3 }.Select(i => new ObjectWithPriority() { Id = i });
您只是创建一个延迟评估的迭代器,这不会分配一个数组/列表来存储ObjectWithPriorty
您的项目.每次枚举迭代器时,它将再次迭代值并ObjectWithPriority
为每次迭代投影一次,但会丢弃它们.
您要做的是在传递查询之前实现查询,因此稍后您将实际修改已分配的列表/数组.这可以使用Enumerable.ToList
或实现Enumerable.ToArray
:
public static IEnumerableCreateObjectsWithPriorities() { var objs = new[] { 1, 2, 3 }.Select(i => new ObjectWithPriority() { Id = i }) .ToList(); ApplyPriorities(objs); return objs; }
您可以额外使用Enumerable.Range
而不是分配固定大小的数组,这将根据请求懒惰地投射数字:
var objs = Enumerable.Range(1, 3).Select(i => new ObjectWithPriority { Id = i }) .ToList();