2010-09-11 40 views
10

MSDN phân loại var theo Types.var: a Loại hoặc từ khóa

biến được khai báo ở phương pháp phạm vi có thể có một kiểu var ngầm

gì 'loại var ngầm' có nghĩa là trong bối cảnh này?

Nói đúng, nếu tôi có giải thích cho các lập trình viên đồng nghiệp.

Tôi có thể nói; var là Loại hoặc tôi phải nói; var là một từ khóa hướng dẫn trình biên dịch xác định chính loại đó.

lưu ý: điều này không có nghĩa là bắt đầu thảo luận về var, cũng như không biết cách sử dụng var. Đối với một lần và cho tất cả tôi muốn biết excactly làm thế nào để mô tả nó và msdn là một chút bối rối, đó là nó.

Trả lời

14

varcontextual keyword - cùng với yield, addget chẳng hạn.

Nói cách khác, bạn có thể sử dụng nó làm định danh mà không cần tiền tố bằng @, nhưng nó vẫn có ý nghĩa đặc biệt đối với trình biên dịch ở một số nơi (nghĩa là tên của một kiểu khai báo biến cục bộ).

Sử dụng var để khai báo biến cục bộ yêu cầu trình biên dịch suy ra loại biến dựa trên biểu thức ở phía bên tay phải. Ví dụ:

var list = new List<string>(); 
var anon = new { Foo = "bar" }; 

Loại listList<string>; loại anon là một loại vô danh , cũng được giới thiệu trong C# 3. Một phần lý do giới thiệu var trong C# 3 là cho phép các biến được nhập mạnh bằng các loại ẩn danh - biến vẫn có kiểu biên dịch thích hợp, thậm chí mặc dù bạn không thể nói rõ loại đó.

Có một vài trường hợp var không hoạt động, tuy nhiên, nếu trình biên dịch không có đủ thông tin:

var cantUseNull = null; 
var cantUseLambda = x => x.Length; 

Có những người khác quá. Trong mỗi trường hợp bạn có thể chỉ cần truyền biểu thức ở phía bên tay phải, để trình biên dịch biết phải sử dụng gì - nhưng trong trường hợp đó bạn cũng có thể chỉ khai báo biến một cách rõ ràng thay thế.

<plug>
Bạn có thể đọc thêm về điều này trong C# in Depth. May mắn thay, chương bao gồm điều này vẫn có sẵn miễn phí từ first edition page (bạn muốn chương 8). Tôi không thể nhớ số tiền tôi đã thay đổi chương này trong ấn bản thứ hai ...
</plug>

+0

và bạn có thể vui lòng giải thích cho tôi ý nghĩa của 'loại biến tiềm ẩn' có nghĩa là trong bài viết msdn như tôi đã trích dẫn không? Bit bị mất trong bản dịch ở đây;) Hơi chỉnh sửa câu hỏi, bạn ở đâu quá nhanh ... –

+0

@Caspar: Có nghĩa là bạn có thể sử dụng 'var' để khai báo kiểu biến, trong trường hợp này kiểu biến thời gian của biến là loại biểu thức ở phía bên tay phải. –

+1

Điều quan trọng là không mất định dạng ở đó, đó là 'loại ngầm ** var **'. Var là một đánh máy ngầm định trong đó kiểu thực được xác định bởi trình biên dịch từ những gì được gán cho nó, tức là 'var i = 10;', trái với một biến được định nghĩa rõ ràng, tức là 'int i = 10;' Implicit thực sự có nghĩa là ngụ ý hoặc suy ra loại. cái đó có giúp ích không? – Lazarus

0

Đó là một phần của cả hai. Về mặt kỹ thuật, khi sử dụng var, biến được đánh mạnh, nhưng trình biên dịch xác định kiểu.Vì vậy, tôi sẽ nói rằng bạn muốn được gần nhất khi nói 'var là một loại'.

0

var là loại, như int là ... nhưng loại chính xác là gì ??

Vâng, trình biên dịch hoạt động cho bạn (đó là ý nghĩa ngầm) dựa trên phần còn lại của dòng.

ví dụ:

var b = "ahjhsad"; 

Tại thời gian biên dịch, var sẽ được thay thế bằng chuỗi.

var được sử dụng như một bàn tay ngắn thuận tiện cho các lập trình viên, thay vì phải viết

List<string> myList = new List<string>(); 

một lập trình viên có thể viết

var myList = new List<string>(); 

và nó có nghĩa là điều tương tự.

+0

Dang, bạn không thể đánh bại được ... – CVertex

+0

" Một loại, chính xác là gì? " Một câu hỏi hay. Đặc tả C# không thực sự * định nghĩa * từ "loại". Nó giả định bạn biết đó là cái gì! –

11

Tôi có thể nói var là một loại , hay tôi phải nói var là một từ khóa rằng chỉ thị các trình biên dịch để xác định loại?

Nó phụ thuộc vào cách bạn nhìn vào nó. Nghiêm túc!

Trình biên dịch C# thực hiện ba loại phân tích về chương trình, mỗi phân tích tiếp theo tiêu thụ kết quả của phần trước. Loại phân tích đầu tiên chúng tôi làm là phân tích từ lexical; chúng tôi lấy văn bản và biến nó thành một loạt các thẻ. Giả sử bạn có

class C { static void Main(){ var x = 123; } } 

Đầu tiên chúng ta xác định rằng những thẻ đang CLASS IDENTIFIER (C) LEFTBRACE static void IDENTIFIER (Main) LEFTPAREN RIGHTPAREN LEFTBRACE IDENTIFIERTHATMIGHTBEAKEYWORD (var) IDENTIFIER (x) bằng INTEGER (123) SEMICOLON RIGHTBRACE RIGHTBRACE.

Ở giai đoạn phân tích này, "var" là số nhận dạng có ghi chú trên đó cho biết rằng đó có thể là từ khóa var chứ không phải từ định danh var.

Phân tích tiếp theo chúng tôi thực hiện là phân tích ngữ pháp trong đó các mã thông báo được sắp xếp thành các nhóm tạo thành "cây phân tích cú pháp". Trong trường hợp này các thẻ sẽ được tổ chức thành cây này (thụt đầu dòng cho thấy mức độ làm tổ trên cây)

declaration of class: CLASS 
    class name: IDENTIFIER(C) 
    class body begins: LEFTBRACE 
    declaration of method: 
     method modifier: STATIC 
     return type: VOID 
     method name: IDENTIFIER(Main) 
     formal parameter declarations: 
      formal parameter declarations begin: LEFTPAREN 
      formal parameter declarations end: RIGHTPAREN 
     method body: 
      method body begins: LEFTBRACE 
      local declaration statement: 
       type: IDENTIFIERTHATMIGHTBEAKEYWORD(var) 
       local name: IDENTIFIER(x) 
       initializer: 
       assignment operator: EQUALS 
       integer literal expression: INTEGER(123) 
       statement ends: SEMICOLON 
      method body ends: RIGHTBRACE 
    class body ends: RIGHTBRACE 

Tại thời điểm này var đã được phân loại như một loại, ngữ pháp. Nó ở nơi chúng tôi mong đợi một tuyên bố loại nếu đây là một chương trình pháp lý theo ngữ pháp.

Nhưng tại thời điểm này, chúng tôi không biết liệu "var" có liên quan đến một loại hoặc đang được sử dụng làm từ khóa hay không. Điều đó yêu cầu phân tích ngữ nghĩa.

Khi phân tích ngữ nghĩa của cây phân tích, chúng ta nói "OK, có một lớp C, nó có phương thức Main, khai báo biến cục bộ x. Biến kiểu cục bộ đó là gì?"

Tại thời điểm này, có hai khả năng. Khả năng đầu tiên là có một lớp, struct, enum, interface hoặc kiểu ủy nhiệm có tên là "var" trong không gian tên chung. (Không có chỉ thị "sử dụng" trong đoạn chương trình này vì vậy chúng tôi không phải kiểm tra bất kỳ không gian tên nào khác và loại không phải là một phần vì vậy chúng tôi không phải kiểm tra bất kỳ khai báo kiểu nào khác). Chúng tôi tìm kiếm không gian tên chung của tất cả các hội đồng được tham chiếu tìm kiếm một loại được gọi là "var". Chúng tôi cũng thực hiện phân tích ngữ nghĩa của các khai báo kiểu trong tất cả các tệp khác, một lần nữa, tìm kiếm một loại được gọi là var.

Nếu chúng tôi tìm thấy, thì "var" dùng để chỉ loại đó.

Nếu chúng tôi không tìm thấy, chúng tôi giả định rằng "var" đang được sử dụng như một từ khóa theo ngữ cảnh giới thiệu một địa phương được đánh máy ngầm.

Vì vậy, để trả lời câu hỏi của bạn:

lexically, mã đoạn "var" là một thẻ nhận dạng với một ghi chú trên đó nói rằng "bằng cách này, điều này thực sự có thể là một từ khóa".

Grammatically, mã thông báo "var" là loại khi xuất hiện ở vị trí trong ngữ pháp có kiểu được mong đợi là.

Ngữ nghĩa, cú pháp loại "var" là loại khi có loại trong phạm vi được gọi là var; nếu không có loại như vậy và "var" đang được sử dụng làm loại khai báo cục bộ thì cú pháp loại "var" không tham chiếu đến một loại. Thay vào đó, nó là một hướng dẫn để trình biên dịch suy ra loại thực tế của địa phương.

+0

Cảm ơn câu trả lời, tôi thực sự thấy rằng lớp công khai var {} overrules var từ khóa như bạn mô tả, do đó, lời giải thích của bạn thực sự có ý nghĩa với tôi, cảm ơn! PS: Điều này có nghĩa là tôi phải hạ cấp Jon? ;) –

+0

và trong mã IDENTIFIERTHATMIGHTBEAKEYWORD là điều thực hiện, trong var x = 123, var có thể là từ khóa –

+0

Tôi không biết bạn có thể tạo kiểu 'var' sẽ ghi đè từ khóa, nhưng tôi cho rằng cần thiết để duy trì tính tương thích ngược. Ngoài sự tò mò, có cách nào để vẫn sử dụng 'var' làm từ khóa, ngay cả khi loại đó nằm trong phạm vi? –

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