简体   繁体   中英

C# linq Select objects in list looking inside another list of objects

I have a class like this:

public class MailMessage
{
    public string From {get; set; };
    public string To {get; set; };   
    public ICollection<Attachment> Attachments { get; set; }
}

public class Attachment
{
  public string Name {get; set;} 
  public byte[] Content {get;set;}   

}

I would like to get all attachments in Attachments collection whose name ends with .pdf.

I tried the following:

List<MailMessage> list = new List<MailMessage>();
List<attachment> pdfAttachmentsCollection = list.Where(x => x.Attachments
                               .Where(attachment => 
                                attachment.Name.EndsWith(".pdf")).Select(y => y.Content));

However, this doesnt work. Any suggestions. It gives error:

Cannot implicitly convert type 'System.Collections.Generic.IEnumerable ' to 'bool'

A couple issues:

  • You need to SelectMany from the MailMessage object to get all attachments in a single collection
  • You're selecting y.Content which is byte[] but trying to get a list of Attachment
  • LINQ returns IEnumerables, not Lists

Rewritten, you probably want to do something like:

List<MailMessage> list = new List<MailMessage>();
IEnumerable<Attachment> pdfAttachmentsCollection = 
    list.SelectMany(message => 
        message.Attachments
            .Where(attachment => attachment.Name.EndsWith(".pdf")));

This is also a good candidate to write as a query expression:

IEnumerable<Attachment> pdfAttachmentsCollection = 
    from message in list 
    from attachment in message.Attachments
    where attachment.Name.EndsWith(".pdf")
    select attachment;

Both of these do the same thing, just with different syntax.

If you want this as a List<Attachment> you can also do .ToList() at the end of either query. As an IEnumerable, it won't be evaluated until you start iterating through it (and depending on how you use it, you might never have the full collection in memory at any time). However, if you do multiple iterations or operations on it, it'll cause it to be evaluated multiple times -- so in those cases .ToList() makes sense for sure.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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