2010-01-21 5 views
20

Als Beispiel, sagen wir, ich habe ein Array von Namen und ich möchte ein Array von Person Objekte erstellen, indem Sie einen Konstruktor aufrufen, der string name dauert.C#: Gibt es eine LINQ-Methode zum Erstellen eines Array von Objekten mit einem Array von Konstruktorparametern?

class Person() 
{ 
    public string Name { get; set; } 

    public Person(string name) 
    { 
     Name = name; 
    } 
} 

... 

static void Main() 
{ 
    string[] names = {"Peter", "Paul", "Mary"}; 
    Person[] people; 

    /* I could do this but I'm wondering if there's a better way. */ 
    List<Person> persons = new List<Person>(); 
    foreach(string name in names) 
    { 
     persons.Add(new Person(name)); 
    } 

    people = persons.ToArray(); 
} 

Ich habe viel zu lange in der .Net 2.0-Welt stecken geblieben und ich versuche, in meinem aktuellen Ausfallzeiten zu modernisieren ...

Antwort

53
// names is string[] 
Person[] people = names.Select(s => new Person(s)).ToArray(); 

Erläuterung:

Enumerable.Select ist die LINQ-Methode für die Projektion. Das heißt, eine Sequenz von Foo s zu nehmen und sie zu Bar s über eine Regel Func<Foo, Bar> zu projizieren, die Foo s isst und ausspuckt Bar s. So

names.Select(s => new Person(s)) 

ist eine Projektion der Sequenz names vom Typ IEnumerable<string> zu einer Sequenz des Typs IEnumerable<Person>. Wenn Sie wissen, funktionale Programmierung spielt es die Rolle von map.

Jetzt gibt es hier einen subtilen Punkt, der es zu verstehen gilt; Dies ist mit ziemlicher Sicherheit einer der wichtigsten, aber leicht zu missverstandenen Aspekte von LINQ. Dies ist das Konzept der verzögerten Ausführung. Wenn wir

IEnumerable<Person> persons = names.Select(s => new Person(s)); 

sagen, dies führt nicht tatsächlich den Vorsprung (das heißt, es nicht noch die Instanzen von Person erstellen, um die string s in names als Konstruktorparameter konstruiert verwenden). Stattdessen erstellt es etwas, das die Regel einfängt, wie die Sequenz names in eine Sequenz von Person projiziert werden soll. Nur wenn diese Regel (bekannt als ein Iterator) tatsächlich ausgeführt wird, findet die Projektion statt.

Eine Möglichkeit, diese Ausführung zu verursachen, besteht darin, die Methode Enumerable.ToArray zu verwenden, die im Grunde sagt, dass ich die Sequenz durchlaufen und mir die Ergebnisse als Array zurückgeben soll.

Es gibt andere Möglichkeiten, die Ausführung zu bewirken. Zum Beispiel

IEnumerable<Person> persons = names.Select(s => new Person(s)); 
foreach(Person p in persons) { 
    Console.WriteLine(p.Name); 
} 

oder

IEnumerable<Person> persons = names.Select(s => new Person(s)); 
Person p = persons.First(); 

welches die "erste" Projektion (d.h. new Person(names[0])), und weist das Ergebnis würde p auszuführen.

Natürlich bedeutet dies nicht einmal in genau das bekommen, was

s => new Person(s) 

ist. Das ist ein Lambda-Ausdruck, und Sie können eine Einführung zu ihnen in meiner Antwort auf How does this LINQ Expression work? bekommen.

+0

Ich bin verwirrt, jetzt 'Select' statt' map' zu sehen, wie in F #. – ChaosPandion

+0

Einfach genug! Vielen Dank!! –

+1

@ChaosPandion: Ja, ich würde gerne wissen, warum die bekannteren 'map' und' fold' nicht anstelle von 'Select' und' Aggregate' zum Beispiel verwendet wurden. – jason

1

Ich poste dies incase jemand anderes braucht ein Licht auf einem etwas anderen Szenario. Das war mein Fall, und ich benutzte Jasons Antwort, um dorthin zu gelangen.

Stellen Sie sich eine Klasse mit dem Namen der Person haben, und Jobbezeichnung und Sie wollen das Objekt füllen:

public class Employee 
{ 
    private string name; 
    private string jobTitle; 

    public Employee(){} 
    public Employee(string name, string job) 
    { 
    this.name = name; 
    this.jobTitle = job; 
    } 

    // getters + setters... 
} 

Dann würden Sie

var IQueryable<Employee> list = from p in context.Persons 
           join j in context.Jobs 
            on p.jobId == j.jobId 
           select new Employee(p.Name, j.Title); 

Dann tun Sie durchlaufen die Liste, um die Instanzen zu erhalten

Verwandte Themen