Cách tốt nhất để chuyển IList hoặc IEnumerable sang Array


99

Tôi có một truy vấn HQL có thể tạo IList các kết quả hoặc IEnumerable kết quả.

Tuy nhiên, tôi muốn nó trả về một mảng Thực thể mà tôi đang chọn, cách tốt nhất để hoàn thành điều đó là gì? Tôi có thể liệt kê thông qua nó và xây dựng mảng hoặc sử dụng CopyTo () một mảng đã xác định.

Có cách nào tốt hơn không? Tôi đã sử dụng phương pháp CopyTo.


4
Có ai đó có một giải pháp mà không có Linq?
Bitterblue

Câu trả lời:


167

Bạn đang sử dụng phiên bản .NET nào? Nếu đó là .NET 3.5, tôi chỉ cần gọi ToArray()và thực hiện với nó.

Nếu bạn chỉ có IEnumerable không chung chung, hãy làm như sau:

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

Nếu bạn không biết kiểu bên trong phương thức đó nhưng những người gọi phương thức biết nó, hãy làm cho phương thức chung chung và thử điều này:

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

Nó là 3.5 nhưng IQuery không có ToArray, cũng không có IEnumerable hoặc IList theo như tôi có thể nói?
jishi

2
Không - chỉ có một phương pháp mở rộng. (Nó không nằm trong chính giao diện.)
Jon Skeet

3
@Shimmy: Vâng, còn có ... ngoài bất cứ điều gì khác, nó cho trình biên dịch biết loại mảng mong đợi! Nếu bạn chỉ muốn object[]sử dụng Cast<object>. Nongeneric IEnumerablekhông có ToArrayphương thức mở rộng, vì vậy bạn không thể chỉ gọi foo.ToArray<object>hoặc bất cứ điều gì tương tự.
Jon Skeet

22
Các ToArrayphương pháp khuyến nông là trong System.Linqkhông gian tên, nghĩ rằng có thể là tốt để biết :).
Tomas Jansson

1
@Alexander: Không trừ khi giá trị được trả về thực sự một mảng thích hợp.
Jon Skeet

47

Đặt nội dung sau vào tệp .cs của bạn:

using System.Linq;

Sau đó, bạn sẽ có thể sử dụng phương thức mở rộng sau từ System.Linq.Enumerable:

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

I E

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

ahh ... dự án thử nghiệm đơn vị không bao gồm linq theo mặc định. Cảm ơn bạn!
zsf222

6

Tôi cảm thấy muốn phát minh lại bánh xe ...

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

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

bạn có thể giải thích câu trả lời của mình và cả ý của bạn khi bạn cảm thấy như mình đang phát minh lại bánh xe không?
ChrisCamp

heh - tôi thực sự như thế này: trong trường hợp ngẫu nhiên, liệt kê thực sự là một mảng, bạn đang bỏ qua phân bổ / sao chép mới cho các bước trong lệnh ToArray()gọi (thông qua Bufferlớp nội bộ ) ... mặc dù nếu ai đó mong đợi "tiêu chuẩn "sao chép hành vi, họ sẽ khá ngạc nhiên.
JerKimball

@Chris: Bởi vì tôi lấy cảm hứng từ chữ ký của phương thức ToArray () trong System.Linq. msdn.microsoft.com/en-us/library/bb298736.aspx
Philippe Matray

Để có thêm sự nực cười, việc thực hiện phương pháp này nên gọiIEnumerable.ToArray()
The Muffin Man

2

Trong trường hợp bạn không có Linq, tôi đã giải quyết nó theo cách sau:

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

        iList.CopyTo(result, 0);

        return result;
    }

Hy vọng nó giúp

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.