在C#中使用Linq进行列表操作

28
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;

namespace ConsoleApplication1
{

    public class Class1  
    {
       static void Main(string[] args)
       {
           List<Car> mylist = new List<Car>();
           Car car1;
           Car car2;
           Car car3;

           car1 = new Car()
           {
               make = "Honda",
               id = 1
           };
           car2 = new Car()
           {
               make = "toyota",
               id = 2
           };

           car3 = new Car()
           {
              make = "Honda",
              id = 3,
              color = "red"
           };

           mylist.Add(car1);
           mylist.Add(car2);
           **////mylist.Where(p => p.id == 1).SingleOrDefault() = car3;**
        }        
    }

    public class Car
    {
        public int id { get; set; }
        public string make { get; set; }
        public string color { get; set; }

    }
}

如何以最好的方式通过用ID为3的本田车替换ID为1的本田车来更新列表。

8个回答

53

除了leppie说的内容外,还有:

int index = mylist.FindIndex(p => p.id == 1);
if(index<0) {
    mylist.Add(car3);
} else {
    mylist[index] = car3;
}

这只是利用现有的FindIndex来定位ID为1的汽车,然后替换或添加它。没有LINQ;没有SQL - 只用了一个lambda和List<T>


感谢您开导我。 - Learner
1
еҰӮжһңжҲ‘жңүдёҖдёӘжҢҮеҗ‘indexеӨ„зҡ„жұҪиҪҰзҡ„еј•з”ЁSelectedCarпјҢйӮЈд№ҲиҝҷдёӘеј•з”Ёдјҡиў«з ҙеқҸиҝҳжҳҜSelectedCarзҺ°еңЁе°ҶжҢҮеҗ‘car3жұҪиҪҰпјҹ - Philippe Lavoie
这是一个类,所以同样的车。但对于结构体来说则不同。 - Marc Gravell
想要添加一个提示:如果你没有用 List 对象开始,你必须首先使用 .ToList() 或类似的方法,FindIndex 是 List 方法,而不是 Collection 或 Array(或其他泛型)方法。 - Nevyn

9
如果您想对多个元素进行更新...
foreach (var f in mylist.FindAll(x => x.id == 1))  
{    
    f.id = car3.id;  
    f.color = car3.color;  
    f.make = car3.make;  
}  

8

这不是 LINQ2SQL。

LINQ 仅用于查询对象,而不能用于更新。


6
您可以使用以下方式:

您可以使用以下方式:

(from car in mylist
where car.id == 1
select car).Update(
car => car.id = 3);

我的参考资料是这个网站。或者下面是Update方法的代码:

public static void Update<T>(this IEnumerable<T> source, params Action<T>[] updates)
{
    if (source == null)
        throw new ArgumentNullException("source");

    if (updates == null)
        throw new ArgumentNullException("updates");

    foreach (T item in source)
    {
        foreach (Action<T> update in updates)
        {
            update(item);
        }
    }
}

+1. 那是一个很棒的链接。我不知道我更喜欢什么,是结果代码变得更加简洁,还是文章的详尽程度。 - Joseph Ferris
-1 Update与List<T>的ForEach相同。这就是为什么IEnumerable中没有包含ForEach的原因(http://blogs.msdn.com/ericlippert/archive/2009/05/18/foreach-vs-foreach.aspx)。 - BlueRaja - Danny Pflughoeft

2

正如Leppie所说,LINQ用于查询而不是更新。但是,它可以用于构建新列表:

mylist = new List<Car>(from car in mylist select car.id == 1? car3 : car)

如果您想使用LINQ,那么这个代码是简短明了的。当然,这段代码比Marc Gravell的建议效率稍低,因为它实际上创建了一个新列表,而不是更新旧列表。


一个很棒的答案。我正在寻找一种简洁的方法,通过从对象列表中选择特定的字符串字段来返回字符串列表,你的方法完美地解决了这个问题。点赞。 - Robert Oschler

2
//Item class
Class Item
{
   public string Name { get; set; }
}

List < Item > myList = new List< Item >()

//Add item to list
Item item = new Item();
item.Name = "Name";

myList.Add(Item);

//Find the item with the name prop

Item item2 = myList.Find(x => x.Name == "Name");

if(item2 != null)
   item.Name = "Changed";

1
只有一个问题,为什么我要为列表中看似如此基本的事情编写Update函数?列表应该有标准方法,如Add()、Delete()、Edit()、Insert()、Replace()....Find()。

列表包含所有这些东西。IList则不包括,因为他们想让接口易于实现给其他人。当然,现在我们有了扩展方法,这些东西可以被提取到IList中。另外:请在将来使用注释来进行此类注释。 - BlueRaja - Danny Pflughoeft

1
List<AvailabilityIssue> ai = new List<AvailabilityIssue>();

ai.AddRange(
    (from a in db.CrewLicences
        where
            a.ValidationDate <= ((UniversalTime)todayDate.AddDays(30)).Time &&
            a.ValidationDate >= ((UniversalTime)todayDate.AddDays(15)).Time
        select new AvailabilityIssue()
        {
            crewMemberId = a.CrewMemberId,
            expirationDays = 30,
            Name = a.LicenceType.Name,
            expirationDate = new UniversalTime(a.ValidationDate).ToString("yyyy-MM-dd"),
            documentType = Controllers.rpmdataController.DocumentType.Licence
        }).ToList());

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接