Tại sao tôi có thể tạo một lớp có tên “var”?


103

Không phải là varmột từ khóa trong C #? Nhưng tại sao tôi có thể làm điều này:

public class var { }

public class main
{
    public static void main(string[] args)
    {
        var testVar = new var();
    }
}

Lớp varđược sử dụng trong mã là varlớp được khai báo trước mainlớp. Và trình biên dịch thậm chí không phàn nàn.

Trong khi khi tôi làm điều này:

public class int { }

hoặc cái này:

public class true { }

Trình biên dịch nói rằng inthoặc truelà một từ khóa và không thể được sử dụng như vậy. Tại sao nó không giống với var?


6
Tại sao bạn sẽ muốn? Thật khó hiểu và khó đọc.
duffymo


31
var'y câu hỏi hay!
Richard

50
Bạn cũng có thể làm var var = "var";trong một phương pháp. Rốt cuộc, đó là thứ sáu.
Henk Holterman

11
Tôi đoán họ đã làm theo cách này để tương thích ngược với mã tạo trước khi "var" có nghĩa là bất kỳ điều gì đặc biệt.
vidstige

Câu trả lời:


101

varkhông phải là một từ khóa theo danh sách này .

nó là một từ khóa theo ngữ cảnh, vì vậy từ ngữ cảnh, trình biên dịch có thể quyết định lớp nào là lớp của bạn và lớp nào là từ khóa theo ngữ cảnh và không có sự nhầm lẫn nào phát sinh.

một từ khóa theo ngữ cảnh là:

được sử dụng để cung cấp một ý nghĩa cụ thể trong mã, nhưng nó không phải là một từ dành riêng trong C #.

để nó không được bảo lưu, bạn có thể sử dụng nó.

Như đã chỉ ra trong các nhận xét ở trên, có một cuộc thảo luận về sự khác biệt cũng như danh sách các từ khóa khác nhau và từ khóa theo ngữ cảnh được thêm vào mỗi phiên bản của c # trên blog Eric Lipperts

Điều thú vị cần lưu ý là kể từ khi tập hợp từ khóa được quyết định trong C # 1.0, không có bổ sung nào, để duy trì khả năng tương thích ngược.


1
Tuy nhiên, nó được phân loại theo "Từ khóa C #" tại đây msdn.microsoft.com/en-us/library/bb383973.aspx ... khó hiểu!
Richard

4
Nhưng nó là một Contextual Keyword. "Từ khóa theo ngữ cảnh được sử dụng để cung cấp một ý nghĩa cụ thể trong mã, nhưng nó không phải là từ dành riêng trong C # . Một số từ khóa theo ngữ cảnh, chẳng hạn như một phần và ở đâu, có ý nghĩa đặc biệt trong hai hoặc nhiều ngữ cảnh."
Tim Schmelter

5
@TimSchmelter Sau đó, "var" là một "từ khóa". Chỉ không phải là một "từ dành riêng", phải không?
luiscubal

2
Tôi đoán nó để duy trì khả năng tương thích với mã cũ - nếu ai đó có một lớp được đặt tên varthì không phải mọi thứ đều hỏng khi nâng cấp C #.
Callum Rogers

1
@CallumRogers: đó chính xác là lý do tại sao nhóm C # đã làm điều này. Tương tự cho các "từ khóa" được giới thiệu sau này như from, join, v.v. (nhân tiện, tất cả đều theo ngữ cảnh).
Abel

18

Trình biên dịch đủ thông minh để biết rằng ngữ cảnh bạn đang sử dụng varlàm tên lớp không bao giờ là ngữ cảnh cho từ khóa để cho phép nó (đó là lý do tại sao nó được định nghĩa là từ khóa theo ngữ cảnh ).


Tôi nghĩ câu trả lời này ít nhất là hơi sai lầm. Trình biên dịch không chính xác "đủ thông minh" để xác định liệu có varđang được sử dụng làm từ khóa trong mã như thế nào không var testVar = new var();. Có, ngữ cảnh, về việc liệu một kiểu tùy chỉnh được đặt tên có varđược xác định hay không, sẽ đóng vai trò quan trọng trong đó, nhưng chính vì trình biên dịch không đủ thông minh trong những trường hợp đó để biết liệu có var testVartham chiếu đến lớp varhay đến từ khóa varmà nó mặc định cho lớp hay không. trong bối cảnh như vậy. Nếu vartừ khóa được đặt tên khác, nó có thể được sử dụng trong cùng một "ngữ cảnh".
HOẶC Mapper

Ngược lại với các từ khóa theo ngữ cảnh khác, chẳng hạn như add- ở đây, trình biên dịch thực sự biết ở mỗi lần xuất hiện liệu từ khóa đó có nghĩa là gì (khai báo sự kiện; mã định danh sẽ không có ý nghĩa gì ở đó) hay mã đang tham chiếu đến một số nhận dạng (loại hoặc tên trong khai báo, sử dụng mã định danh trong thân phương thức; từ khóa sẽ không có ý nghĩa gì ở đó).
HOẶC Người vẽ bản đồ

12

Một cách khác để xem xét điều này: "var" làm từ khóa không có trong phiên bản đầu tiên của C # (không giống như "int" và "true"), vì vậy bạn có thể đã viết một số mã sau đó có một lớp gọi là "var". Điều này là hoàn toàn tốt và hợp pháp. Sau đó, khi "var" được thêm vào ngôn ngữ, các nhà thiết kế đã rất tốt khi chỉ đặt nó trở thành một từ khóa trong một số ngữ cảnh nhất định, vì vậy lớp var hiện có của bạn vẫn hoạt động.

Đây là một trong những thách thức thực sự của thiết kế ngôn ngữ - làm thế nào để thêm các tính năng mới mà không phá vỡ mã hiện có và không làm cho các tính năng mới trở nên cồng kềnh khi sử dụng.


8

Trong các phiên bản C # trước phiên bản 3, các biến cục bộ được nhập ngầm chưa được hỗ trợ, do đó varkhông có ý nghĩa đặc biệt và có thể xác định các biến và lớp được đặt tên var. Chương trình ví dụ của bạn là hợp pháp, bởi vì cả hai lần xuất hiện vartrong đều tham mainchiếu đến lớp var.

C # 3 và các phiên bản mới hơn tương thích trở xuống, vì vậy mã được viết bằng C # trước phiên bản 3 vẫn được biên dịch với các trình biên dịch mới.

inttruelà các từ khóa kể từ C # 1.


3

Từ khóa có thể được đặt trước theo ngữ cảnh. Khi mã nguồn được phân tích cú pháp, ngữ cảnh đó được thiết lập như một phần của cây phân tích cú pháp. Việc đánh giá các từ khóa diễn ra trong bối cảnh đó. Vì vậy, trong trường hợp này, var không ở trong ngữ cảnh dành riêng và sẽ không có nghĩa giống như khi bạn sử dụng nó trong một câu lệnh gán. Tôi tin rằng một lý do cho sự linh hoạt này là var đã được giới thiệu trong C # 3, vì vậy việc đặt nó ở mọi nơi có thể đã phá vỡ khả năng tương thích ngược trong một số chương trình, trong khi việc sử dụng nó làm khai báo kiểu biến sẽ không được biên dịch trong các phiên bản trước đó, vì vậy không có sự đứt gãy.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.