简体   繁体   English

如何在列表中找到特定元素<T> ?

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

My application uses a list like this:我的应用程序使用这样的列表:

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

Using the Add method, another instance of MyClass is added to the list.使用Add方法, MyClass另一个实例被添加到列表中。

MyClass provides, among others, the following methods: MyClass提供了以下方法:

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

How can I find a specific instance of MyClass by means of using the GetId method?如何通过使用GetId方法找到MyClass的特定实例? I know there is the Find method, but I don't know if this would work here?!我知道有Find方法,但我不知道这在这里是否有效?!

Use a lambda expression使用 lambda 表达式

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

Note: C# has a built-in syntax for properties.注意:C# 有一个内置的属性语法。 Instead of writing getter and setter as ordinary methods (as you might be used to from Java), write不是将 getter 和 setter 编写为普通方法(就像您在 Java 中可能习惯的那样),而是编写

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

value is a contextual keyword known only in the set accessor. value是仅在 set 访问器中已知的上下文关键字。 It represents the value assigned to the property.它表示分配给属性的值。

Since this pattern is often used, C# provides auto-implemented properties .由于经常使用这种模式,C# 提供了自动实现的属性 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).但是,后备变量是隐藏的并且不可访问(但是,它可以从 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 Id within the class but not from outside.这使您可以在类内设置Id ,但不能从外部设置。 If you need to set it in derived classes as well you can also protect the setter如果您还需要在派生类中设置它,您还可以保护设置器

public string Id { get; protected set; }

And finally, you can declare properties as virtual and override them in deriving classes, allowing you to provide different implementations for getters and setters;最后,您可以将属性声明为virtual属性并在派生类中覆盖它们,从而允许您为 getter 和 setter 提供不同的实现; just as for ordinary virtual methods.就像普通的虚方法一样。


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 属性。 Getter-only auto-properties are true read-only properties, unlike auto-implemented properties with a private setter. 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")请参阅: .NET 编译器平台(“Roslyn”)
New Language Features in C# 6 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.请注意,在这种情况下,setter 必须是一个表达式。 It cannot be a statement.它不能是一个声明。 The example above works, because in C# an assignment can be used as an expression or as a statement.上面的示例有效,因为在 C# 中,赋值可以用作表达式或语句。 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 = 0 is equivalent to x = (y = (z = 0)) and has the same effect as the statements x = 0; y = 0; z = 0;这允许您一次为多个变量赋值: x = y = z = 0等价于x = (y = (z = 0))并且与语句x = 0; y = 0; z = 0;具有相同的效果x = 0; y = 0; z = 0; x = 0; y = 0; z = 0; . .

Since C# 9.0 you can use read-only (or better initialize-once) properties that you can initialize in an object initializer.从 C# 9.0 开始,您可以使用可以在对象初始值设定项中初始化的只读(或更好的初始化一次)属性。 This is currently not possible with getter-only properties.目前这对于仅使用 getter 的属性是不可能的。

public string Name { get; init; }

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

Since C# 10.0 (Nov 2021), we can access the automatically created backing field with the new field keyword.从 C# 10.0(2021 年 11 月)开始,我们可以使用 new field关键字访问自动创建的支持字段。

// Removes time part in setter
public DateTime HiredDate { get; init => field = value.Date(); }
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 SingleOrDefault may be what you want或者如果只有一个并且您想强制执行诸如SingleOrDefault类的SingleOrDefault可能是您想要的

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

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

尝试:

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

Or if you do not prefer to use LINQ you 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
    }
}

You can also use LINQ extensions:您还可以使用LINQ扩展:

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

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

MyClass found = list.Find(item => item.GetID() == ID);
public List<DealsCategory> DealCategory { get; set; }
int categoryid = Convert.ToInt16(dealsModel.DealCategory.Select(x => x.Id));

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.这里“var query”正在生成您通过搜索变量提供的搜索条件。 Then "DuePaymentstring.Select" is selecting the data matching your given criteria.然后“DuePaymentstring.Select”正在选择符合您给定条件的数据。 Feel free to ask if you have problem understanding.如果您在理解上有问题,请随时提问。

console.writeline(“ Hello world”);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM