2008-11-28 40 views
6

Tôi có câu hỏi về việc sử dụng new[].C# Sử dụng mới []

Hãy tưởng tượng này:

Object.SomeProperty = new[] {"string1", "string2"}; 

đâu SomeProperty hy vọng một mảng các chuỗi.

Tôi biết đoạn mã này sẽ hoạt động. Nhưng tôi muốn biết nó làm gì dưới mui xe. new[] có tạo thành một thể hiện của lớp object và trong số SomeProperty nó tự động chuyển đổi nó thành đối tượng string không?

Cảm ơn

Trả lời

16

OK, vẫn còn chút nhầm lẫn tại đây.

Suy luận đang diễn ra không có gì với kiểu Object.SomeProperty, nhưng mọi thứ cần làm với các loại biểu thức trong bộ khởi tạo mảng. Nói cách khác, bạn có thể làm:

object o = new[] { "string1", "string2" }; 

và o vẫn sẽ là tham chiếu đến mảng chuỗi.

Về cơ bản, trình biên dịch nhìn vào một biểu hiện như thế này:

new[] { A, B, C, D, ... } 

(trong đó A, B, C, D vv là những biểu hiện) và cố gắng để làm việc ra các loại mảng đúng để sử dụng. Nó chỉ xem xét các loại A, B, C và D (vv) làm loại phần tử mảng. Lấy tập hợp các loại ứng cử viên này, nó cố gắng tìm một loại mà tất cả những người khác có thể được chuyển đổi hoàn toàn. Nếu không có chính xác một loại thì trình biên dịch sẽ khiếu nại.

Vì vậy, ví dụ:

new[] { new Form(), new MemoryStream() } 

sẽ không biên dịch - không MemoryStream cũng không Form là chuyển đổi sang bên kia. Tuy nhiên:

new[] { GetSomeIDisposable(), new MemoryStream() } 

sẽ được coi như một IDisposable[] bởi vì có một chuyển đổi ngầm MemoryStream-IDisposable. Tương tự:

new[] { 0, 1, 3.5 } // double[] 
new[] { 1, 3, 100L } // long[] 
15

Đây chỉ là đường cú pháp. Trình biên dịch sẽ suy ra các loại thực sự cần thiết ở đây và tạo ra mã mà là tương đương với cấu trúc rõ ràng:

Object.SomeProperty = new string[] {"string1", "string2"}; 

Không có những điều như new[] đó được thực hiện tại thời gian chạy.

2

Trình biên dịch thay thế:

Object.SomeProperty = new[] {"string1", "string2"}; 

với:

Object.SomeProperty = new string[] {"string1", "string2"}; 
+0

Object.SomeProperty = {"string1", "string2"}; Không có bất kỳ trình biên dịch C# nào mà tôi từng thấy! Bạn chỉ có thể làm điều đó trong quá trình khởi tạo. – leppie

+0

khởi tạo, là khởi tạo biến. ví dụ. string [] foo = {"thanh", "baz"}; – leppie

+0

@leppie, aboslutely đúng. Tôi đứng sửa –

3

Nó được tạm dịch để:

string[] $temp = new string[2]; 
$temp[0] = "string1"; 
$temp[1] = "string2"; 
Object.SomeProperty = $temp; 

Điều thú vị là, var x = new[] { "string1", "string2" }; công trình là tốt, nó có thể suy ra x là a string[], nhưng var x = { "string1", "string2" }; không thành công.

+0

Đó là bởi vì một mảng là một kiểu tham chiếu phải được cấp phát mới. Không có gì là đi đường cú pháp mà đi. –

+0

Có, nhưng khi đưa ra một kiểu, thì cú pháp không phải là mới [] 'sẽ đưa ra loại, đi qua IEnumerable , vì vậy khi nó chỉ có var, tại sao nó không thể mặc định mương cuối cùng thành T []? –

1

Tôi hy vọng từ câu trả lời của bạn, bạn không bị lẫn lộn giữa thay thế loại và suy luận kiểu ở đây! Tôi giả định loại Object.SomeProperty là chuỗi [], mặc dù do hiệp phương sai mảng có thể là đối tượng [] (chú ý điều này sẽ không là một điều tốt - hãy xem Eric Lippert's post về chủ đề này!).

Trình biên dịch thực hiện gõ suy luận sử dụng để phân tích - nó xác định rằng "string1" và "string2" là kiểu string, và do đó nó có hiệu quả thay thế mã của bạn với: -

Object.SomeProperty = new string[] {"string1", "string2"}; 

Nó thực sự là đơn giản như thể! Tất cả được thực hiện tại thời gian biên dịch, không có gì trong thời gian chạy.

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