Найкращий спосіб конвертувати IList або IEnumerable в Array


99

У мене є HQL-запит, який може генерувати або ІЛІСТЬ результатів, або ІНечислений результат.

Однак я хочу, щоб він повернув масив сутності, який я вибирав, який був би найкращий спосіб досягти цього? Я можу або перерахувати через нього, і створити масив, або використовувати CopyTo () визначений масив.

Чи є кращий спосіб? Я пішов із методом CopyTo.


4
Хтось має рішення без Linq?
Bitterblue

Відповіді:


167

Яку версію .NET ви використовуєте? Якщо це .NET 3.5, я б просто зателефонував ToArray()і закінчив з ним.

Якщо у вас є лише загальний IEnumerable, зробіть щось подібне:

IEnumerable query = ...;
MyEntityType[] array = query.Cast<MyEntityType>().ToArray();

Якщо ви не знаєте типу в цьому методі, але абоненти методу його знають, зробіть метод загальним і спробуйте наступне:

public static void T[] PerformQuery<T>()
{
    IEnumerable query = ...;
    T[] array = query.Cast<T>().ToArray();
    return array;
}

Це 3,5, але IQuery не має ToArray, а також IEnumerable або IList, наскільки я можу зрозуміти?
джиші

2
Ні - існує лише один метод розширення. (Це не в самому інтерфейсі.)
Джон Скіт

3
@Shimmy: Так, є ... окрім всього іншого, це говорить компілятору, який масив очікувати! Якщо ви хочете object[]лише справедливого використання Cast<object>. У nongeneric IEnumerableнемає ToArrayметоду розширення, тому ви не можете просто зателефонувати foo.ToArray<object>або щось подібне.
Джон Скіт,

22
Метод ToArrayрозширення знаходиться у System.Linqпросторі імен, і це, мабуть, корисно знати :).
Томаш Янссон,

1
@Alexander: Тільки якщо значення, яке повертається, насправді не є відповідним масивом.
Джон Скіт,

47

Помістіть у свій файл .cs наступне:

using System.Linq;

Тоді ви зможете використовувати наступний метод розширення з System.Linq.Enumerable:

public static TSource[] ToArray<TSource>(this System.Collections.Generic.IEnumerable<TSource> source)

Тобто

IEnumerable<object> query = ...;
object[] bob = query.ToArray();

ах ... проектний блок тестування за замовчуванням не включає linkq. Дякую!
zsf222

6

Мені хочеться заново винаходити колесо ...

public static T[] ConvertToArray<T>(this IEnumerable<T> enumerable)
{
    if (enumerable == null)
        throw new ArgumentNullException("enumerable");

    return enumerable as T[] ?? enumerable.ToArray();
}

Ви можете пояснити свою відповідь, а також те, що ви маєте на увазі під тим, що відчуваєте, що ви винаходите колесо?
ChrisCamp

хе - я насправді приблизно такий: у випадковому випадку перелічене насправді є масивом, ви пропускаєте нове виділення / копіювання до кроків у ToArray()виклику (через внутрішній Bufferклас) ... хоча якщо хтось очікував "стандартного "поведінка копіювання, вони були б дуже здивовані.
JerKimball

@Chris: Тому що мене надихнула підпис методу ToArray () в System.Linq. msdn.microsoft.com/en-us/library/bb298736.aspx
Філіпп Матрей

Для додаткової смішності реалізація цього методу повинна закликатиIEnumerable.ToArray()
Чоловік-

2

Якщо у вас немає Linq, я вирішив це наступним чином:

    private T[] GetArray<T>(IList<T> iList) where T: new()
    {
        var result = new T[iList.Count];

        iList.CopyTo(result, 0);

        return result;
    }

Сподіваюся, це допомагає

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.