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

Rob*_*uch 105 c# properties list find

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

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

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

MyClass 除其他外,提供以下方法:

public void SetId(String Id);
public String GetId();
Run Code Online (Sandbox Code Playgroud)

如何MyClass通过使用该GetId方法找到特定的实例?我知道有Find方法,但我不知道这是否适用于此?!

Oli*_*bes 235

使用lambda表达式

MyClass result = list.Find(x => x.GetId() == "xy");
Run Code Online (Sandbox Code Playgroud)

注意:C#具有内置的属性语法.写,而不是编写getter和setter方法(正如你可能习惯于Java)

private string _id;
public string Id
{
    get
    {
        return _id;
    }
    set
    {
        _id = value;
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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

public string Id { get; set; }
Run Code Online (Sandbox Code Playgroud)

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

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

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

MyClass result = list.Find(x => x.Id == "xy"); 
Run Code Online (Sandbox Code Playgroud)

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

public string Id { get; private set; }
Run Code Online (Sandbox Code Playgroud)

这使您可以Id在类中设置,但不能从外部设置.如果您还需要在派生类中设置它,您也可以保护setter

public string Id { get; protected set; }
Run Code Online (Sandbox Code Playgroud)

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


从C#6.0(Visual Studio 2015,Roslyn)开始,您可以使用内联初始化程序编写仅具有getter的自动属性

public string Id { get; } = "A07"; // Evaluated once when object is initialized.
Run Code Online (Sandbox Code Playgroud)

您也可以在构造函数中初始化仅限getter的属性.与仅具有私有设置器的自动实现属性不同,仅限Getter的自动属性是真正的只读属性.

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

public string Id { get; set; } = "A07";
Run Code Online (Sandbox Code Playgroud)

从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); } }
Run Code Online (Sandbox Code Playgroud)

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

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

public string Name
{
    get => _name;                                // getter
    set => _name = value;                        // setter
}
Run Code Online (Sandbox Code Playgroud)

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

  • 很好的回答,谢谢.对于db操作,它看起来像这样:`IQueryable <T> result = db.Set <T>().Find(// just id here //).ToList();`它已经知道你正在寻找对于主键.仅供参考. (2认同)

zel*_*lio 17

var list = new List<MyClass>();
var item = list.Find( x => x.GetId() == "TARGET_ID" );
Run Code Online (Sandbox Code Playgroud)

或者,如果只有一个,你想强制执行类似SingleOrDefault可能是你想要什么

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

if ( item == null )
    throw new Exception();
Run Code Online (Sandbox Code Playgroud)

  • 如果要抛出异常,为什么要使用 singleOrDefault,使用 Single() (2认同)

Amr*_*ngh 9

尝试:

 list.Find(item => item.id==myid);
Run Code Online (Sandbox Code Playgroud)


Bjø*_*ørn 7

或者,如果您不喜欢使用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
    }
}
Run Code Online (Sandbox Code Playgroud)


Guf*_*ffa 5

您还可以使用LINQ扩展:

string id = "hello";
MyClass result = list.Where(m => m.GetId() == id).First();
Run Code Online (Sandbox Code Playgroud)

  • 或者 First 的另一个重载:`MyClass result = list.First(m =&gt; m.GetId() == id); ` (4认同)