2013-05-21 4 views
1

У меня есть объект IList<Person>. Класс Person имеет поле, FirstName, LastName и т.д.Получение IList <field_type> от IList <object_type>

У меня есть функция, которая принимает IList<string> и я хочу передать в списке FirstNames в том же порядке IList<Person> объекта. Есть ли способ сделать это без создания списка со всеми именами из списка Person?

Что делать, если я могу изменить функцию, чтобы принять другой параметр (кроме ILIst<Person>, функция специфична для строк, а не для лиц), может быть IEnumerable<string>? Я бы предпочел использовать IList<string>.

+0

@TimSchmelter: Он имеет '' IList ... он хочет изменить, что в '' IList , содержание которого являются 'Person.FirstName'. –

+0

Вы действительно хотите 'IList ', или 'IReadOnlyList ' достаточно? 'IList ' также включает в себя такие методы, как 'Add', который не будет работать для вас. A 'IReadOnlyList Выберите (этот список IReadOnlyList , Func func). Метод расширения будет достаточно простым для создания. – hvd

ответ

4

Enumerable.Select вернет IEnumerable строк (имена) для вас.

http://msdn.microsoft.com/en-us/library/bb548891.aspx

myFunction(people.Select(o => o.FirstName))

Можно также добавить в ToList(), если вы действительно хотите, чтобы пройти в List

myFunction(people.Select(o => o.FirstName).ToList())

Enumerable.Select это метод, который был введен в C# 3 как часть LINQ. Узнайте больше о LINQ here. См. Краткое объяснение отложенного исполнения here.

+0

Я немного больше читал о LINQ, и я был впечатлен тем, что компилятор .NET может оптимизировать некоторые из запросов. В частности, если вы используете метод Count в IEnumerable, LINQ не должен выполнять итерацию, но может использовать метод Count в коллекции, если он существует. – bpeikes

0

Вы можете использовать свои методы IEnumerable<T> (где T - тип значения). Например, public void Foo(IEnumerable<string> firstNames) { ... }. Это будет действительным, если вы хотите только перебирать список и не обращаться к нему по индексу, поскольку IList<T> позволит вам сделать это.

Предполагая, что с этим все в порядке, вы можете просто создать объект Enumerator, выполнив метод LINQ: myPersonsList.Select(person => person.FirstName);. Из-за того, как работает Enumerable (отложенное выполнение), он более эффективен, чем создание нового списка, а затем повторяет его.

0

Я чувствую, что оба ответа, опубликованные выше, помогут решить вашу проблему, но лучше использовать методы расширения, а не собственный метод.

Пример вставляется для справки.

class Program 
{ 
    static void Main(string[] args) 
    { 
     List<Person> persons = new List<Person>(); 
     persons.Select(c => c.FirstName).DoSomething(); 
    } 
} 

public static class StringListExtension 
{ 
    public static int DoSomething(this IEnumerable<string> strList) 
    { 
     return strList.Count(); 
    } 
} 

class Person 
{ 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
} 
Смежные вопросы