【问题标题】:How to search for an object in List<object> having its field value如何在 List<object> 中搜索具有其字段值的对象
【发布时间】:2012-01-05 03:31:58
【问题描述】:

问题是如何从 List 中获取具有其字段值的对象

我有一个名为 f_objects 的列表,里面装满了对象。

private List<F_object> f_objects;

我还有一个带有一些值的字符串:

string name = "something";

F_object 有一个方法返回其名为 name 的字段:

public string GetName()
{
    return this.name;
}

是否有用于比较列表中的对象与该字段值的内置方法?或者我应该做一个循环并像这样比较:

foreach(F_object ob in f_objects)
{
    if String.Equals(name, ob.GetName())
    F_object found = ob;
} 

【问题讨论】:

  • 感谢大家这么快的回放!

标签: c# oop list object


【解决方案1】:

使用 LINQ:

List<F_object> found = f_objects.Where(obj => obj.GetName() == name).ToList();

这是所有匹配对象的列表。

编辑:如果您期望或只关心获取一个不同的值,Rune FS 的回答也有使用 .Single().First() 而不是 .Where() 的好建议。

【讨论】:

  • 当我需要搜索多个匹配项时,您的解决方案将帮助我。现在我需要选择一个对象(因为名称是唯一的)所以 Alex 的解决方案最适合我。感谢您的帮助!
  • @Alan Alex 解决方案不会给你一个项目,它会给你一个 IEnumerabl 其中的值将指示与 f_objects 中的特定对象匹配的名称的位置
  • @AlanKuras,如果它适合您的需要,请记住接受答案。
  • @Rune FS:我不知道它如何返回一个 IEnumerable,如果我将我的解决方案放入编译器,结果集是 IEnumerable
  • @Alex 因为您已经将代码从确实返回 IEnumerable 的代码更改为在我发布评论后返回 IEnumerable 的代码我很确定你知道什么我指的是:)
【解决方案2】:

在 linq 中有多种方法可以做到这一点。 第一个是使用.Where。如果可以有更多匹配项,这将满足您的需求

IEnumerable<F_object> result = f_objects.Where(obj=>obj.GetName() == name);

第二种选择是如果您只关心第一次点击,即使可能有多个,在这种情况下使用.First

f_object result = f_objects.First(obj=>obj.GetName() == name);

或者如果零命中是可接受的情况(非例外)

f_object result = f_objects.FirstOrDefault(Obj=>obj.GetName() == name);

如果您应该只点击一次,请使用.Single

f_object result = f_objects.Single(obj=>obj.GetName() == name);

或者,如果您只能获得一次或零次点击,请使用 .SingleOrDefault

f_object result = f_objects.SingleOrDefault(obj=>obj.GetName() == name);

【讨论】:

  • .First/.Single 是要记住的好点,我倾向于忘记它们的存在。我在这里发布了一个答案,但我已经给你投票了。
【解决方案3】:
List<...> items = ... ;
string name = ...;
var found = items.Find( i => string.Equals(name, i.GetName()) );

【讨论】:

    【解决方案4】:

    你可以使用 LINQ。

    var objectswith_something = f_objects.Where(fo => fo.GetName().Equals(name));
    

    如果你只想要第一个,使用

    f_objects.Where(fo => fo.GetName().Equals(name)).FirstOrDefault();`
    

    【讨论】:

    • 这个解决方案最适合我,因为只有一个具有指定名称的对象。
    • fo.GetName().Equals(name) 返回什么?一个对象还是一个布尔值?您的答案返回 bool 数组(或单个 bool)
    • 如果字段不同则返回布尔列表 false,如果字段相等则返回 true。它过滤哪个 OP 正在寻找
    • Where 需要一个 Func - 使用 Equals 返回一个 bool。
    • 这确实返回了一个IEnumerable&lt;F_object&gt;fo.GetName().Equals(name)fo.GetName() == name 完全相同,并且行为与您预期的一样。如果您使用.Select() 调用而不是.Where(),它只会返回IEnumberable&lt;bool&gt;
    【解决方案5】:

    仍然有人在他们的项目中无法使用 LINQ,所以这里是没有它的版本:

    F_object found = f_objects.Find(delegate(F_object f)
    {
        return f.GetName().Equals(name);
    });
    

    【讨论】:

      【解决方案6】:

      假设您使用的是 3.5 或更高版本,最好的方法是使用 Linq 表达式进行搜索。

      例如你会写

      IEnumerable<F_object> filteredListOff_objects f_objects.Where(f_object=>f_object.GetName() == "something");
      

      获取名称为“something”的对象的 IEnumberable

      【讨论】:

        【解决方案7】:

        使用查询语法的另一个版本。我认为这比带有 lambda 表达式的代码更具可读性。最终还是一样。

        string name = "something";
        var foundQuery = from s in f_objects
                         where s.Name == name
                         select s;
        

        我将声明一个属性名称而不是 GetName()。 然后你可以用 foreach 遍历查询:

        foreach (string s in foundQuery)
           ...
        

        或将其转换为 List 或带有 ToList 或 ToArray 的数组。

        【讨论】:

          猜你喜欢
          • 2020-08-27
          • 1970-01-01
          • 1970-01-01
          • 2020-09-02
          • 1970-01-01
          • 2012-09-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多