Tôi vừa mới bắt đầu học C # và trong phần giới thiệu về mảng, họ đã chỉ ra cách thiết lập một biến dưới dạng một mảng nhưng có vẻ như người ta phải chỉ định độ dài của mảng khi gán, vì vậy điều gì sẽ xảy ra nếu tôi không biết độ dài của mảng?
Câu trả lời:
Mảng phải được gán độ dài. Để cho phép bất kỳ số phần tử nào, hãy sử dụng List
lớp.
Ví dụ:
List<int> myInts = new List<int>();
myInts.Add(5);
myInts.Add(10);
myInts.Add(11);
myInts.Count // = 3
"Arrays must be assigned a length"
- trong một static
phương thức bên ngoài Main()
, tôi đã thực hiện khai báo String[] tokens = null
và không khởi tạo nó nhưng làm sao tôi có thể gọi "Hello.World".Split('.')
nó mà không gặp System.NullReferenceException
lỗi?
Sử dụng List<>
để tạo 'mảng' có độ dài không xác định.
Sử dụng List<>.ToArray()
để trả về một mảng thực, và không phải là a List
.
var list = new List<int>();
list.Add(1);
list.Add(2);
list.Add(3);
var array = list.ToArray();
Một chút thông tin cơ bản:
Như đã nói, nếu bạn muốn có một bộ sưu tập động, hãy sử dụng a List<T>
. Bên trong, một Danh sách cũng sử dụng một mảng để lưu trữ. Mảng đó có kích thước cố định giống như bất kỳ mảng nào khác. Khi một mảng được khai báo là có kích thước, nó không thay đổi. Khi bạn thêm một mục vào a List
, nó sẽ được thêm vào mảng. Ban đầu, phần List
bắt đầu với một mảng mà tôi tin rằng có độ dài là 16. Khi bạn cố gắng thêm mục thứ 17 vào List
, điều xảy ra là một mảng mới được phân bổ, (tôi nghĩ) có kích thước gấp đôi kích thước của mảng cũ. , như vậy 32 mặt hàng. Sau đó, nội dung của mảng cũ được sao chép vào mảng mới. Vì vậy, mặc dù a List
có thể tỏ ra năng động đối với người quan sát bên ngoài, nhưng bên trong nó cũng phải tuân thủ các quy tắc.
Và như bạn có thể đoán, việc sao chép và phân bổ các mảng không miễn phí vì vậy người ta nên nhắm đến việc có càng ít những mảng đó càng tốt và để làm điều đó bạn có thể chỉ định (trong hàm tạo của List
) kích thước ban đầu của mảng, mà trong một kịch bản hoàn hảo là vừa đủ lớn để chứa mọi thứ bạn muốn. Tuy nhiên, đây là tối ưu hóa vi mô và nó không bao giờ quan trọng đối với bạn, nhưng thật tuyệt khi biết bạn thực sự đang làm gì.
Bạn có thể tạo một mảng với kích thước được đặt thành một biến, tức là
int size = 50;
string[] words = new string[size]; // contains 50 strings
Tuy nhiên, kích thước đó không thể thay đổi sau này, nếu bạn quyết định bạn cần 100 từ. Nếu bạn cần kích thước thực sự năng động, bạn sẽ cần sử dụng một loại cấu trúc dữ liệu khác. Cố gắng List
.
string[] words = new string(',', size - 1).Split(',');
ngay bây giờ chúng được khởi tạo bằng ""
.
Sử dụng ArrayList
if trong .NET 1.x hoặc List<yourtype>
if trong .NET 2.0 hoặc 3.x.
Tìm kiếm chúng trong System.Collections
và System.Collections.Generics
.
hãy thử một danh sách chung thay vì mảng
Như đã nêu chi tiết ở trên, Danh sách chung chung <> là cách tốt nhất để làm điều đó.
Nếu bạn bị mắc kẹt trong .NET 1. *, thì bạn sẽ phải sử dụng lớp ArrayList để thay thế. Điều này không có kiểm tra kiểu thời gian biên dịch và bạn cũng phải thêm truyền - lộn xộn.
Các phiên bản kế tiếp cũng đã triển khai các biến thể khác nhau - bao gồm cả các biến thể an toàn chuỗi.
Nếu bạn thực sự cần sử dụng một mảng thay vì một danh sách, thì bạn có thể tạo một mảng có kích thước được tính tại thời điểm chạy như vậy ...
Ví dụ: tôi muốn một mảng hai chiều có kích thước n x n. n sẽ được nhận vào lúc chạy từ người dùng
int n = 0;
bool isInteger = int.TryPase(Console.ReadLine(), out n);
var x = new int[n,n];
List<int[]> myInts = new List<int[]>();
có thể làm việc.