C# 如何在 List<T> 中找到特定元素?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9854917/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 10:55:37  来源:igfitidea点击:

How can I find a specific element in a List<T>?

c#listpropertiesfind

提问by Robert Strauch

My application uses a list like this:

我的应用程序使用这样的列表:

List<MyClass> list = new List<MyClass>();

List<MyClass> list = new List<MyClass>();

Using the Addmethod, another instance of MyClassis added to the list.

使用该Add方法,另一个实例MyClass被添加到列表中。

MyClassprovides, among others, the following methods:

MyClass提供以下方法:

public void SetId(String Id);
public String GetId();

How can I find a specific instance of MyClassby means of using the GetIdmethod? I know there is the Findmethod, but I don't know if this would work here?!

如何MyClass通过使用该GetId方法找到特定实例?我知道有这个Find方法,但我不知道这在这里是否有效?!

采纳答案by Olivier Jacot-Descombes

Use a lambda expression

使用 lambda 表达式

MyClass result = list.Find(x => x.GetId() == "xy");


Note: C# has a built-in syntax for properties. Instead of writing getter and setter methods (as you might be used to from Java), write

注意:C# 有一个内置的属性语法。而不是编写 getter 和 setter 方法(就像您在 Java 中可能习惯的那样),编写

private string _id;
public string Id
{
    get
    {
        return _id;
    }
    set
    {
        _id = value;
    }
}

valueis a contextual keyword known only in the set accessor. It represents the value assigned to the property.

value是仅在集合访问器中已知的上下文关键字。它表示分配给属性的值。

Since this pattern is often used, C# provides auto-implemented properties. They are a short version of the code above; however, the backing variable is hidden and not accessible (it is accessible from within the class in VB, however).

由于经常使用这种模式,C# 提供了 自动实现的属性。它们是上述代码的简短版本;但是,后备变量是隐藏的并且不可访问(但是,它可以从 VB 中的类中访问)。

public string Id { get; set; }

You can simply use properties as if you were accessing a field:

您可以像访问字段一样简单地使用属性:

var obj = new MyClass();
obj.Id = "xy";       // Calls the setter with "xy" assigned to the value parameter.
string id = obj.Id;  // Calls the getter.


Using properties, you would search for items in the list like this

使用属性,您可以像这样搜索列表中的项目

MyClass result = list.Find(x => x.Id == "xy"); 


You can also use auto-implemented properties if you need a read-only property:

如果您需要只读属性,也可以使用自动实现的属性:

public string Id { get; private set; }

This enables you to set the Idwithin the class but not from outside. If you need to set it in derived classes as well you can also protect the setter

这使您可以Id在类内而不是从外部设置 。如果您还需要在派生类中设置它,您还可以保护设置器

public string Id { get; protected set; }


And finally, you can declare properties as virtualand override them in deriving classes, allowing you to provide different implementations for getters and setters; just as for ordinary virtual methods.

最后,您可以将属性声明为virtual并在派生类中覆盖它们,从而允许您为 getter 和 setter 提供不同的实现;就像普通的虚方法一样。



Since C# 6.0 (Visual Studio 2015, Roslyn) you can write getter-only auto-properties with an inline initializer

从 C# 6.0 (Visual Studio 2015, Roslyn) 开始,您可以使用内联初始值设定项编写仅限 getter 的自动属性

public string Id { get; } = "A07"; // Evaluated once when object is initialized.

You can also initialize getter-only properties within the constructor instead. Getter-only auto-properties are trueread-only properties, unlike auto-implemented properties with a private setter.

您还可以在构造函数中初始化 getter-only 属性。Getter-only 自动属性是真正的只读属性,与具有私有 setter 的自动实现属性不同。

This works also with read-write auto-properties:

这也适用于读写自动属性:

public string Id { get; set; } = "A07";

Beginning with C# 6.0 you can also write properties as expression-bodied members

从 C# 6.0 开始,您还可以将属性编写为表达式主体成员

public DateTime Yesterday => DateTime.Date.AddDays(-1); // Evaluated at each call.
// Instead of
public DateTime Yesterday { get { return DateTime.Date.AddDays(-1); } }

See: .NET Compiler Platform ("Roslyn")
         New Language Features in C# 6

请参阅:.NET 编译器平台(“Roslyn”)
         C# 6 中的新语言功能

Starting with C# 7.0, both, getter and setter, can be written with expression bodies:

C# 7.0开始,getter 和 setter 都可以用表达式主体编写:

public string Name
{
    get => _name;                                // getter
    set => _name = value;                        // setter
}

Note that in this case the setter must be an expression. It cannot be a statement. The example above works, because in C# an assignment can be used as an expression or as a statement. The value of an assignment expression is the assigned value where the assignment itself is a side effect. This allows you to assign a value to more than one variable at once: x = y = z = 0is equivalent to x = (y = (z = 0))and has the same effect as the statements x = 0; y = 0; z = 0;.

请注意,在这种情况下,setter 必须是一个表达式。它不能是一个声明。上面的示例有效,因为在 C# 中,赋值可以用作表达式或语句。赋值表达式的值是赋值本身的副作用。这允许您一次为多个变量分配一个值:与 statementsx = y = z = 0等效x = (y = (z = 0))并具有相同的效果x = 0; y = 0; z = 0;

The next version of the language, C# 9.0, probably available in November 2020, will allow read-only (or better initialize-once) properties that you can initialize in an object initializer. This is currently not possible with getter-only properties.

该语言的下一个版本 C# 9.0 可能会在 2020 年 11 月推出,它将允许您可以在对象初始值设定项中初始化的只读(或更好的初始化一次)属性。目前这对于仅使用 getter 的属性是不可能的。

public string Name { get; init; }

var c = new C { Name = "c-sharp" };

回答by zellio

var list = new List<MyClass>();
var item = list.Find( x => x.GetId() == "TARGET_ID" );

or if there is only one and you want to enforce that something like SingleOrDefaultmay be what you want

或者如果只有一个并且您想强制执行类似的事情SingleOrDefault可能是您想要的

var item = list.SingleOrDefault( x => x.GetId() == "TARGET" );

if ( item == null )
    throw new Exception();

回答by Amritpal Singh

Try:

尝试:

 list.Find(item => item.id==myid);

回答by David Heffernan

You can solve your problem most concisely with a predicate written using anonymous method syntax:

您可以使用匿名方法语法编写的谓词最简洁地解决您的问题:

MyClass found = list.Find(item => item.GetID() == ID);

回答by Guffa

You can also use LINQextensions:

您还可以使用LINQ扩展:

string id = "hello";
MyClass result = list.Where(m => m.GetId() == id).First();

回答by Bj?rn

Or if you do not prefer to use LINQyou can do it the old-school way:

或者,如果您不喜欢使用LINQ,您可以使用老式的方式:

List<MyClass> list = new List<MyClass>();
foreach (MyClass element in list)
{
    if (element.GetId() == "heres_where_you_put_what_you_are_looking_for")
    {

        break; // If you only want to find the first instance a break here would be best for your application
    }
}

回答by Muhammad Armaghan

public List<DealsCategory> DealCategory { get; set; }
int categoryid = Convert.ToInt16(dealsModel.DealCategory.Select(x => x.Id));

回答by Khandkar Asif Hossain

You can create a search variable to hold your searching criteria. Here is an example using database.

您可以创建一个搜索变量来保存您的搜索条件。这是一个使用数据库的例子。

 var query = from o in this.mJDBDataset.Products 
             where o.ProductStatus == textBox1.Text || o.Karrot == textBox1.Text 
             || o.ProductDetails == textBox1.Text || o.DepositDate == textBox1.Text 
             || o.SellDate == textBox1.Text
             select o;

 dataGridView1.DataSource = query.ToList();

 //Search and Calculate
 search = textBox1.Text;
 cnn.Open();
 string query1 = string.Format("select * from Products where ProductStatus='"
               + search +"'");
 SqlDataAdapter da = new SqlDataAdapter(query1, cnn);
 DataSet ds = new DataSet();
 da.Fill(ds, "Products");
 SqlDataReader reader;
 reader = new SqlCommand(query1, cnn).ExecuteReader();

 List<double> DuePayment = new List<double>();

 if (reader.HasRows)
 {

  while (reader.Read())
  {

   foreach (DataRow row in ds.Tables["Products"].Rows)
   {

     DuePaymentstring.Add(row["DuePayment"].ToString());
     DuePayment = DuePaymentstring.Select(x => double.Parse(x)).ToList();

   }
  }

  tdp = 0;
  tdp = DuePayment.Sum();                        
  DuePaymentstring.Remove(Convert.ToString(DuePaymentstring.Count));
  DuePayment.Clear();
 }
 cnn.Close();
 label3.Text = Convert.ToString(tdp + " Due Payment Count: " + 
 DuePayment.Count + " Due Payment string Count: " + DuePaymentstring.Count);
 tdp = 0;
 //DuePaymentstring.RemoveRange(0,DuePaymentstring.Count);
 //DuePayment.RemoveRange(0, DuePayment.Count);
 //Search and Calculate

Here "var query" is generating the search criteria you are giving through the search variable. Then "DuePaymentstring.Select" is selecting the data matching your given criteria. Feel free to ask if you have problem understanding.

这里的“var query”正在生成您通过搜索变量提供的搜索条件。然后“DuePaymentstring.Select”正在选择符合您给定条件的数据。如果您在理解上有问题,请随时提问。