2010-08-04 22 views
8

Tôi cố gắng để biên dịch mã sau trong C#:Sử dụng mảng initializer '{}' nhiều lần cho cùng một biến không biên dịch

String[] words = {"Hello", "Worlds"}; 
words = {"Foo", "Bar"}; 

Và Tôi nhận lỗi biên dịch như:

Error 1 Invalid expression term '{' 
Error 2 ; expected 
Error 3 Invalid expression term ',' 

Mặt khác, nếu tôi thử

String[] words = { "Hello", "Worlds" }; 
words = new String[] {"Foo", "Bar"}; 

Nó biên dịch tốt. Theo MSDN,

int[] a = {0, 2, 4, 6, 8}; 

nó chỉ đơn giản là một cách viết tắt cho một biểu thức tạo mảng tương đương:

int[] a = new int[] {0, 2, 4, 6, 8}; 

Tại sao không phải là mẫu mã đầu tiên biên dịch?

Trả lời

5

C# đặc tả 12,6 Mảng initializers

Trong một lĩnh vực hoặc khai báo biến, kiểu mảng là loại lĩnh vực hoặc nhiều biến thể công bố. Khi bộ khởi tạo mảng được sử dụng trong khai báo trường hoặc biến, chẳng hạn như: int [] a = {0, 2, 4, 6, 8}; nó chỉ đơn giản là viết tắt cho một biểu thức tạo mảng tương đương: int [] a = new int [] {0, 2, 4, 6, 8};

String[] words = { "Hello", "Worlds" }; 

là một tuyên bố nhưng

words = {"Foo", "Bar"}; 

thì không.

+0

Cần chú ý hơn khi đọc tài liệu. Cảm ơn – Babar

9

Chính xác, cú pháp khởi tạo ngắn chỉ được phép trong khai báo. Không phải trong một tuyên bố bình thường.

String[] words = new string[]{ "Hello", "Worlds" }; // full form 
String[] words = { "Hello", "Worlds" }; // short hand, special rule 
words = {"Foo", "Bar"};     // not allowed 
words = new String[] {"Foo", "Bar"};  // allowed, full form again 

Ký pháp viết tay ngắn chỉ được phép khi được sử dụng như phần (rhs) của tuyên bố.

1

Theo các tài liệu bạn liên kết đến, initializers mảng chỉ có giá trị tự trong lĩnh vực này hoặc khai báo biến - cho các bài tập biến, bạn phải xác định new[] trước:

Trong một biểu thức tạo mảng (trường hợp chung), loại mảng ngay trước bộ khởi tạo. Trong trường hoặc khai báo biến, loại mảng là loại trường hoặc biến được khai báo.

2

Theo cùng một trang MSDN, cú pháp này cụ thể cho việc khởi tạo biến mảng; nó không phải là một cú pháp mảng đa năng.

Tuy nhiên, đây là gần:

String[] words = { "Hello", "Worlds" }; 
// words = {"Foo", "Bar"}; 
words = new[] {"Foo", "Bar"}; 
2

Các lỗi biên dịch bạn đang đề cập đến là do cú pháp invaild.

// variable declaration so constructor may be assumed 
String[] words = { "Hello", "Worlds" }; 

// attempted variable assignment using invalid syntax 
words = {"Foo", "Bar"}; 

// explicit constructor 
words = new String[] {"Foo", "Bar"}; 

// as a note this would also work. Here the type of the array is assumed. 
words = new [] {"Foo", "Bar"}; 
1

Trình khởi tạo mảng được sử dụng như một phần của khai báo biến là đặc biệt, về cơ bản. (Tôi không thể tra cứu tham chiếu cụ thể ngay bây giờ, nhưng tôi có thể làm như vậy sau.) Bên ngoài một tuyên bố biến, trình biên dịch không thực sự chú ý nhiều đến thực tế là có một nhiệm vụ - biểu thức trên tay phải bên phải đứng trên hai chân của nó, như nó đã được.

Trong C# 3 bạn có thể sử dụng một hình thức hơi viết tắt:

words = new[] {"Foo", "Bar"}; 

này sẽ suy ra kiểu của mảng (tại thời gian biên dịch) từ các yếu tố bên trong nó ... và giả định đó là tương thích với biến mục tiêu, nhiệm vụ sẽ hoạt động. Cú pháp này hoạt động trong một ngữ cảnh tổng quát hơn - bạn có thể sử dụng nó để chuyển mảng như các đối số phương thức, ví dụ.

Không có cách nào sử dụng biểu mẫu "được viết tắt hoàn toàn" bên ngoài các khai báo biến.


Phải thừa nhận rằng có một số biểu hiện mà không có một loại, chẳng hạn như biểu thức lambda.

0

Trong khi khởi tạo, bạn khai báo rõ ràng loại mảng, làm cho viết tắt này rõ ràng và rõ ràng. Tuy nhiên, sau này trong mã, một chút mơ hồ bắt đầu leo ​​vào. Bạn có thể, trong lý thuyết, đang cố gắng để thiết lập một mảng các đối tượng, ví dụ. Chắc chắn, bạn có lẽ muốn nó là một chuỗi các chuỗi, nhưng vì mục đích tránh các lỗi logic, trình biên dịch không muốn giả sử một cái gì đó như vậy trừ khi nó cực kỳ rõ ràng những gì bạn đang cố gắng làm.

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