Как конвертировать Список <Company>в Список <ICompany> - PullRequest
4 голосов
/ 05 января 2010

Я хотел бы конвертировать List<Company> в List<ICompany>

ICompany - это интерфейс, который реализует Company.

public List<ICompany> FindAll()
{
    List<Company> companies = new List<Company>();

    var query = from c in _scope.Extent<Company>()
                select c;

    companies = query.ToList();

    return companies.ToList<ICompany>(); // doesn't work
    //and
    return companies.ToList(); // doesn't work
}

Есть мысли?

Ответы [ 4 ]

25 голосов
/ 05 января 2010

Использование Enumerable.Cast:

return query.Cast<ICompany>().ToList();

Несколько комментариев:

List<Company> companies = new List<Company>();

Это создает новый список. Но вы никогда не используете его, потому что через две строки вы получите

companies = query.ToList();

перезаписывает созданный вами список (а в промежуточной строке вы никогда не обращаетесь к companies). Если вы хотите, вы можете объявить и получить результаты одним махом:

List<Company> companies = query.ToList();

Во-вторых, все это не нужно, если вы просто пытаетесь вернуть список результатов. Краткость (в определенной степени) - большой плюс в программировании. «Меньше значит больше» - это выражение, так как меньше кода означает меньше кода для написания, меньше кода для тестирования и меньше кода для обслуживания. Мгновенное повышение производительности за счет написания меньшего количества кода! Вот краткая версия вашего метода:

public List<ICompany> FindAll() {
    var query = from c in _scope.Extent<Company>()
                select c;
    return query.Cast<ICompany>().ToList();
}

или даже

public List<ICompany> FindAll() {
    return _scope.Extent<Company>().Cast<ICompany>().ToList();
}

В-третьих, как минимум, вы должны рассмотреть возможность возврата IList вместо List. Лучше кодировать интерфейсы, а не конкретные типы. Это отделяет ваш код от деталей реализации, делая код более удобным для изменения и более легким для тестирования.

Наконец, вы должны проверить, действительно ли вам нужно вернуть List. Какие методы в списке вы используете? Если вы просто используете его для перечисления результатов (foreach(var item in list)), вам следует вместо этого вернуть IEnumerable<ICompany>:

public IEnumerable<ICompany> FindAll() {
    return _scope.Extent<Company>().Cast<ICompany>();
}
3 голосов
/ 05 января 2010
return companies.Cast<ICompany>().ToList(); 
1 голос
/ 05 января 2010

В дополнение к ответам Enumerable.Cast, если вам приходится много ходить между коллекциями Company и ICompany, другим предложением может быть создание собственного класса коллекции из Collection с именем CompanyCollection и его реализация IList .

Если вы используете .NET 4.0 (в настоящее время в бета-версии), вы можете воспользоваться универсальной ковариацией , которая позволяет вам делать это неявно.

0 голосов
/ 05 января 2010

Если по какой-то причине вы не хотите использовать Enumerable.Cast (хотя я бы порекомендовал сделать это вместе с другими комментариями), вы всегда можете сделать это:

companies = query.ToList();
List<ICompany> ret = new List<ICompany>();
foreach (Company c in companies) 
{
   ret.Add(c as ICompany);
}

Это почти то же самое решение, что и у Скеолана, но если (ICompany)c не удастся, оно выбрасывает. В моем коде c as ICompany вернет ноль, если приведение не выполнено.

...