2010-01-14 24 views
39

Tôi thấy phương thức này Array.ConvertAll nhưng yêu cầu phải có một đối số là Converter. Tôi không thấy lý do tại sao tôi cần một bộ chuyển đổi, khi tôi đã được xác định là một tiềm ẩn trong lớp học của tôi:C# Cast toàn bộ mảng?

public static implicit operator Vec2(PointF p) 
    { 
     return new Vec2(p.X, p.Y); 
    } 

Tôi đang cố gắng để cast một mảng của PointF s tới một mảng của Vec2 s. Có cách nào tốt đẹp để làm điều này? Hoặc tôi nên chỉ cần hút nó lên và viết (một) chuyển đổi hoặc vòng lặp trên các yếu tố?

+0

Tôi đã học được một số nội dung thú vị qua câu hỏi này và câu trả lời của nó! Cảm ơn! –

+3

@Terry: Tôi hỏi rất nhiều câu hỏi tầm thường bởi vì tôi luôn ngạc nhiên bởi câu trả lời :) Thật dễ dàng để giải quyết một vấn đề, nhưng khó để làm điều đó một cách thanh lịch. – mpen

+0

Nhân bản: http://stackoverflow.com/questions/944174/best-way-to-cast-from-animal-to-dog – Mikhail

Trả lời

69

Giải pháp LINQ được đề xuất sử dụng Cast/'Chọn' là tốt, nhưng vì bạn biết bạn đang làm việc với một mảng ở đây, sử dụng ConvertAll là khá hiệu quả hơn và đơn giản.

var newArray = Array.ConvertAll(array, item => (NewType)item); 

Sử dụng ConvertAll nghĩa a) mảng được chỉ lặp qua một lần, không phải hai lần, b) các hoạt động được tối ưu hóa hơn cho mảng (không sử dụng IEnumerator<T>).

Đừng để loại Converter<TInput, TOutput> gây nhầm lẫn cho bạn - nó chỉ là một đại biểu đơn giản và do đó bạn có thể chuyển biểu thức lambda cho nó, như được hiển thị ở trên.

+0

Hoạt động hoàn hảo! Cảm ơn bạn! Tôi nghĩ tôi phải định nghĩa ''. – mpen

+3

Không sao cả. Và vâng, trong C# 2.0 và trước khi bạn sẽ phải xác định một loại - may mắn thay những ngày đó đã biến mất. – Noldorin

15

Truyền không xem xét chuyển đổi tiềm ẩn do người dùng xác định để bạn không thể truyền mảng như vậy. Bạn có thể sử dụng thay vì chọn:

myArray.Select(p => (Vec2)p).ToArray(); 

Hoặc viết một bộ chuyển đổi:

Array.ConvertAll(points, (p => (Vec2)p)); 

Sau này có lẽ hiệu quả hơn như kích thước của kết quả được biết trước.

+2

Đánh dấu là chính xác, tôi đã xóa câu trả lời của mình. –

+0

Cảm ơn bạn đã sao chép câu trả lời của mình dưới dạng chỉnh sửa ... – Noldorin

+0

Tôi đã viết nó trước khi tôi xem bài đăng của bạn. Điều chính xác đã xảy ra với tôi chỉ một giờ trước đây ở đây: http://stackoverflow.com/questions/2067778/sql-for-delete-query/. Thỉnh thoảng no xảy ra. Đừng lấy nó một cách cá nhân - nó chỉ là một sự trùng hợp ngẫu nhiên mà hai người có cùng câu trả lời ngay cả khi nó giống như một bản sao khác. –

19

Như một bản cập nhật cho câu hỏi cũ này, bây giờ bạn có thể làm:

myArray.Cast<Vec2>().ToArray(); 

nơi myArray chứa các đối tượng nguồn, và Vec2 là loại mà bạn muốn truyền tới.

+0

Rất thanh lịch, cảm ơn. – Nyerguds

+1

Yêu cầu không gian tên: using System.Linq –

Các vấn đề liên quan