2010-07-30 42 views
8

xem xét mẫu mã sau đây:C# phạm vi câu hỏi

      // line # 
{      // 1 
         // 2 
    {     // 3 
     double test = 0; // 4 
    }     // 5 
         // 6 
    double test = 0;  // 7 
}      // 8 

này cung cấp cho các lỗi

Một biến cục bộ có tên là 'test' không thể được khai báo trong phạm vi này bởi vì nó sẽ cung cấp cho một ý nghĩa khác nhau để 'test', đã được sử dụng trong phạm vi 'con' để biểu thị một cái gì đó khác

Nhưng tôi không hiểu tại sao? Biến kiểm tra bên ngoài bắt đầu ở dòng 7 và không nằm trong dòng 2, do đó, vấn đề khai báo biến thứ hai được gọi là test ở dòng 4 với phạm vi kết thúc ở dòng 5 là bao nhiêu?

+7

Các thông báo lỗi khá nhiều nói lên tất cả. Các nhà thiết kế ngôn ngữ đã làm theo cách này để khuyến khích mọi người sử dụng các tên biến khác nhau trong một khối scoped để tránh nhầm lẫn, mặc dù họ có thể đã viết phạm vi chặt chẽ hơn. Vì vậy, các biến trong phạm vi con phải có đặt tên duy nhất. –

+1

http://blogs.msdn.com/b/ericlippert/archive/2009/11/02/simple-names-are-not-so-simple.aspx – LukeH

+0

Đây là ví dụ về 'Pit of Success' triết lý trong thiết kế của các phần khác nhau của .NET (ref http://blogs.msdn.com/b/brada/archive/2003/10/02/50420.aspx) – AakashM

Trả lời

3

Đây là câu hỏi thường gặp; xem thêm:

Lambda variable scope

C# going nuts when I declare variables with the same name as the ones in a lambda

C# variable scoping: 'x' cannot be declared in this scope because it would give a different meaning to 'x'

Variable scope confusion in C#

Câu trả lời là: đọc được thông báo lỗi kỹ lưỡng hơn. Thông báo lỗi cho biết chính xác vấn đề là gì: bạn không được phép sử dụng cùng một tên đơn giản để có nghĩa là hai thứ khác nhau trong cùng một khối.

Ví dụ:

class C 
{ 
    int x; 
    void M() 
    { 
     int x; 
    } 
} 

hoàn toàn hợp pháp. Lưu ý rằng phạm vi của các bên ngoài x chồng chéo phạm vi của x bên trong. Đó là không phải bất hợp pháp để có phạm vi chồng chéo có cùng tên trong phạm vi trong cả hai.

Đây không phải là quy phạm pháp luật:

class C 
{ 
    int x; 
    void M() 
    { 
     Console.WriteLine(x); // this.x 
     { 
      int x; 
     } 
    } 
} 

Một lần nữa, hai phạm vi cả với một x chồng chéo là hoàn toàn hợp pháp. Có gì là bất hợp pháp là tên đơn giản x được sử dụng hai bình hai biến khác nhau trong cùng một khối - đó là, trong khối ngoài của M(), mà chứa khối bên trong của M.

Chương Trình có cùng tên đơn giản là được sử dụng có nghĩa là hai thứ khác nhau trong cùng một khối là gây nhầm lẫnlỗi dễ bị và do đó là bất hợp pháp trong C#.

Để biết thêm thông tin chi tiết đọc bài viết của tôi về đề tài này:

http://blogs.msdn.com/b/ericlippert/archive/tags/simple+names/

+0

Cảm ơn bạn rất nhiều vì câu trả lời chi tiết này! –

10

biến được scoped trong khối họ được khai báo trong, nó không có vấn đề gì dòng họ đang ở.

Đọc về scopes trong spec ngôn ngữ C#.

Từ spec:

Phạm vi của một biến địa phương tuyên bố trong một địa phương biến-khai (Section 8.5.1) là các khối, trong đó tuyên bố xảy ra.

Và:

Phạm vi có thể được lồng vào nhau, và một phạm vi bên trong có thể redeclare ý nghĩa của một tên từ một phạm vi bên ngoài. (Tuy nhiên, điều này không loại bỏ hạn chế áp đặt bởi Mục 3.3 trong một khối lồng nhau không thể khai báo biến cục bộ có cùng tên với biến cục bộ trong khối bao quanh.)

+0

Cảm ơn lời giải thích và liên kết, Oded/Robert! BTW đây là báo giá có liên quan từ trang được liên kết http://msdn.microsoft.com/en-us/library/aa691132%28VS.71%29.aspx: "Phạm vi có thể được lồng nhau và phạm vi bên trong có thể redeclare Tuy nhiên, điều này không loại bỏ sự hạn chế áp đặt bởi Phần 3.3 trong một khối lồng nhau, không thể khai báo một biến cục bộ có cùng tên như một biến cục bộ trong một khối bao quanh.) " –

+0

@ stefan.at.wpf - đúng. Đã cập nhật câu trả lời để bao gồm thông tin này. – Oded

0

+1 , Tôi đồng ý với bạn, nhưng đó không phải là cách mà thông số được viết. Nó làm cho trình biên dịch dễ dàng hơn tôi chắc chắn. Ngoài ra, tôi nghĩ có thể lập luận rằng không nên làm điều này để làm cho mã dễ hiểu hơn.

+0

Cảm ơn tster, tôi cũng đoán đây là lý do chính và có, nó thực sự không hữu ích để làm sth. như trong mẫu của tôi (chỉ cần chuyển đổi thứ tự của các khối ...), chỉ cần không hiểu tại sao trong thời điểm đầu tiên ;-) –

+2

I * đảm bảo * bạn nó * không * làm cho trình biên dịch dễ dàng hơn. Các mã trong trình biên dịch thực hiện quy tắc này là một số mã hairiest, khó hiểu nhất mà tôi từng thấy. Có * rất nhiều lỗi trong mã này mà bạn sẽ không bao giờ gặp phải vì chúng là tất cả các trường hợp góc rất tối nghĩa. Lý do cho tính năng này là vì nó ngăn chặn các lỗi trong mã người dùng, không phải vì nó làm cho công việc của tôi dễ dàng hơn. Nó làm cho công việc của tôi hơi khó hơn một chút. –

+0

@Eric Lippert, Cảm ơn lời chứng chuyên gia. – tster