如何使用linq获取内存位置?

时间:2011-11-07 23:37:17

标签: c# linq

我有一个列表,我正在尝试找到一个特定元素,然后我想编辑该元素。

storage.First(item => item.dirty == true).dirty = false; 

然而,这似乎不起作用,因为我猜测First正在创建另一个列表并填充它。是否有功能可以做我想做的事情?

以下是我使用的数据类型:

class BaseRegister {
  public bool dirty {set;get;}
}

List <BaseRegister> storage = new List <BaseRegister> ();

3 个答案:

答案 0 :(得分:4)

这将有效,但前提是您的类型(包含.dirty)是一个类。

如果这是一个结构,你将无法以这种方式改变结构。使用结构,您需要替换集合中的整个结构,使用LINQ扩展非常困难,因为它们是为查询而非编辑而设计的。

如果(storage)类型实施IList<T>,例如List<YourClass>,您可以使用:

int index = storage.FindIndex(item => item.dirty);
var item = storage[index];
item.dirty = false;
storage[index] = item;

请注意,这很麻烦,但主要是因为它必须完全重置列表中结构的值。

这,顺便说一下,部分为什么可变结构是一个坏主意。如果您发现这是您认为需要的类型,您可能需要考虑一个类。通常,任何具有“脏”标志的项目都可能是可变的,因此,应该是一个类而不是结构。

答案 1 :(得分:2)

你的程序肯定有其他问题让你感到困惑。为避免疑义,这是一个使用您的数据类型的完整程序。输出是:

---Before---
True
False
True
---After---
False
False
True

代码是:

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;

namespace ConsoleApplication40 {
  internal class Program {
    private static List<BaseRegister> storage=new List<BaseRegister>();

    private static void Main(string[] args) {
      storage.Add(new BaseRegister {dirty=true});
      storage.Add(new BaseRegister {dirty=false});
      storage.Add(new BaseRegister {dirty=true});
      Dump("---Before---");
      storage.First(item => item.dirty==true).dirty=false;
      Dump("---After---");
    }

    private static void Dump(string title) {
      Debug.WriteLine(title);
      foreach(var br in storage) {
        Debug.WriteLine(br.dirty);
      }
    }

    private class BaseRegister {
      public bool dirty { set; get; }
    }
  }
}

答案 2 :(得分:0)

如果item是引用类型,则应更改dirty属性/字段。

如果item是值类型,First将返回一个副本,甚至不应该编译。

首先不是创建列表,而是返回满足条件的序列中的第一个项目。