Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I use a collection initializer with LINQ to return a fully populated collection?

Tags:

c#

linq

I would like to rewrite the following code in one line, using LINQ. Is it possible?

var to = new MailAddressCollection();

foreach(string recipient in recipients)
{
    to.Add(new MailAddress(recipient));
}

Something like the following would be ideal. As written it returns multiple MailAddressCollections:

var to = recipients.Select(r => new MailAddressCollection() {new MailAddress(r)});

Note that these are framework classes, so I cannot rewrite MailAddressCollection to include a constructor argument.

like image 486
freshr Avatar asked Jun 02 '11 08:06

freshr


People also ask

What is collection initializer in IEnumerable?

Collection initializers. Collection initializers let you specify one or more element initializers when you initialize a collection type that implements IEnumerable and has Add with the appropriate signature as an instance method or an extension method. The element initializers can be a simple value, an expression, or an object initializer.

How do I initialize an object in a collection?

The following collection initializer uses object initializers to initialize objects of the Cat class defined in a previous example. Note that the individual object initializers are enclosed in braces and separated by commas. You can specify null as an element in a collection initializer if the collection's Add method allows it.

What is Anan object and collection initializer?

An object and collection initializer is an interesting and very useful feature of C# language. This feature provides a different way to initialize an object of a class or a collection. This feature is introduced in C# 3.0 or above.

Why do we use object initializers in LINQ?

Although object initializers can be used in any context, they are especially useful in LINQ query expressions. Query expressions make frequent use of anonymous types, which can only be initialized by using an object initializer, as shown in the following declaration.


3 Answers

MailAddressCollection doesn't have a constructor that takes list of recipients. If you really want to do it in one line, you can write the following:

    var to = recipients.Aggregate(new MailAddressCollection(), 
        (c, r) => { c.Add(new MailAddress(r)); return c; });
like image 174
Grozz Avatar answered Oct 30 '22 02:10

Grozz


There is a 1 line alternative that doesn't use linq which I provide for completeness. Personally I couldn't recommend it due to the unnecessary string manipulation.

It does however provide a terse solution.

var to = new MailAddressCollection() { string.join(",", recipients) };
like image 39
Jodrell Avatar answered Oct 30 '22 01:10

Jodrell


You could write an extension method on IEnumerable<MailAddress> which returns a MailAddressCollection:

public static MailAddressCollection ToAddressCollection(this IEnumerable<MailAddress> source)
{
  var to = new MailAddressCollection();
  foreach(string r in source)
  {
    to.Add(new MailAddress(r));
  }
  return to;
}

Then use it like this:

var to = recipients.Select(r => new MailAddress(r)).ToAddressCollection();
like image 36
Stefan Avatar answered Oct 30 '22 02:10

Stefan