2009-06-28 36 views
9

Tôi đang sử dụng C# và khá khó chịu khi tôi không thể gửi mảng bắt đầu từ một điểm nhất định như trong C++.Nhận mảng bắt đầu bằng offset

giả mã này:

int[] array = new int[32]; 
foobar (array + 4); //send array starting from the 4th place. 

đây là một cú pháp lạ cho C# bởi vì chúng tôi không có bất kỳ gợi ý sử dụng được, nhưng chắc chắn có một cách để làm điều đó? Có .Skip(), nhưng tôi nghĩ nó tạo ra một mảng mới, đó là thứ tôi không thích.

Tùy chọn của tôi là gì?

+3

FYI, bỏ qua không tạo ra mảng mới. Nó tạo ra một hàm số _array mới đã bỏ qua các mục n đầu tiên. –

+1

Những gì tôi đã thực hiện khi chuyển mã C++ thành C# sử dụng thành ngữ của con trỏ nội bộ này đến một mảng là thực hiện một cấu trúc ArrayPtr bất biến mà thực hiện các toán tử do người dùng định nghĩa [] - +. Lớp ArrayPtr xử lý các chi tiết của việc tìm ra các offset nằm bên trong mảng thực. –

+0

Làm thế nào bạn xác định rằng việc tạo một mảng mới là quá nhiều chi phí? – nos

Trả lời

1

Bạn chỉ có thể chuyển giá trị bù vào chính hàm đó làm tham số. Sau đó, hàm sẽ lặp qua các phần tử từ [mảng + offset] tới mảng.Length. Điều đó, hoặc sao chép mảng phụ vào một mảng mới, nhưng điều đó có lẽ không tối ưu.

+1

vâng, tôi biết điều đó, nhưng đó là điều xấu xí. – Nefzen

+0

Vâng, tôi thích đề xuất của tv tốt hơn, nhưng tôi không biết về "quá xấu xí". Nó khá là chật chội, bạn nghĩ mảng gì.Skip đang làm gì? –

+0

vấn đề là nó dễ bị lỗi – Nefzen

17

Bạn có thể muốn chuyển nó dưới dạng IEnumerable<int> thay vì làm mảng. Sau đó bạn có thể sử dụng bỏ qua và nó sẽ đơn giản di chuyển vòng lặp qua số lượng các phần tử bị bỏ qua. Sử dụng theo cách này, bạn sẽ không phải sử dụng ToArray() và tạo một bản sao của phần của mảng được đề cập. Tất nhiên, IEnumerable có thể không phù hợp với những gì bạn muốn làm, nhưng đó là khó khăn để nói từ câu hỏi của bạn.

public void FooBar(IEnumerable<int> bar) 
{ 
    ... 
} 

int[] array = new int[32]; 
FooBar(array.Skip(4)); 
+2

chi phí để biến một mảng thành một số đếm là gì? – Nefzen

+6

Zero - mảng đã triển khai IEnumerable tvanfosson

+2

http://msdn.microsoft.com/en-us/library/system.array.aspx Trong .NET Framework phiên bản 2.0, lớp Array triển khai System.Collections.Generic .IList (T), System.Collections.Generic.ICollection (T), và System.Collections.Generic.IEnumerable (T) chung giao diện. Việc triển khai được cung cấp cho các mảng tại thời gian chạy và do đó không hiển thị với các công cụ xây dựng tài liệu. – tvanfosson

3

Tôi có thể đánh giá cao những gì bạn đang cố gắng làm nhưng bạn không thể (và không nên cố gửi) tham chiếu đến "một phần của mảng". Trong C#, mảng là các đối tượng, không phải con trỏ. Đó là một sự khác biệt quan trọng. Gửi một tham chiếu đến "một phần của một đối tượng" chỉ không có ý nghĩa.

Làm cách nào để "một phần của đối tượng" hoạt động khi bạn chuyển cho phương pháp?

  • Điều gì sẽ array.Length trở lại?
  • Điều gì sẽ xảy ra nếu phương pháp được gọi là sắp xếp mảng (chỉ là một phần của mảng)?
  • Điều gì xảy ra nếu mảng là tham chiếu tự (tức là các phần tử mảng tham chiếu đến các phần khác của mảng)? Bạn bằng cách nào đó "bị khóa" truy cập các phần tử mảng không phải là được chuyển vào phương pháp?
  • Phương thức được gọi là hiện có cần kiểm tra cờ để biết liệu chúng có "đối tượng đầy đủ không?" Điều đó sẽ phá vỡ rất nhiều mã hiện có.

Nếu phương pháp của bạn cần chỉ là một phần của mảng (và bạn không muốn tạo ra một bản sao cục bộ), giải pháp tốt nhất là để vượt qua tham chiếu mảng và bất kỳ thông tin khác mà bạn cần truy cập vào phần bạn nhu cầu.

Thưởng thức,

Robert C. Cartaino

+0

có, một tham chiếu mảng sẽ là tốt. Phương thức này không cần biết nó hoạt động trên một tập hợp con của mảng, nó chỉ đọc hoặc ghi trên nó. Một tham chiếu đến một mảng với cùng một giao diện sẽ là tuyệt vời. Trên thực tế tôi nghĩ rằng tôi có thể viết rằng bản thân mình, nhưng tôi không nghĩ rằng nó là giá trị thêm chi phí. – Nefzen

3

NET có System.ArraySegment wrapper - không may, nó hoàn toàn vô dụng vì nó không thực hiện IEnumerable.

+1

Đối với tin tốt: trong .net 4.5, ArraySegment sẽ thực hiện IEnumerable (cũng như IList). –

+0

@jdv Cuối cùng. Đưa họ đủ lâu. –

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