2012-05-23 36 views
5

Tôi đã đọc câu hỏi này (What is the scope of a lambda variable in C#?)Tại sao phạm vi biến Lambda tồn tại bên ngoài LINQ Query?

Nhưng đó là phạm vi biến Lambda bên trong LINQ Query.

Bây giờ câu hỏi của tôi

phép nói rằng tôi có một truy vấn LINQ rất đơn giản.

var Foo = FoobBar.Select(x => x); 
var x = somefunction(); 

Trình biên dịch nói: A local variable 'x' cannot be declared in this scope because it would give a different meaning to 'x', which is already used in a 'child' scope to denote something else.

Tại sao vậy? Không nên biến Lambda tồn tại khi truy vấn LINQ kết thúc?

EDIT: Sau khi đọc câu trả lời tôi đi đến kết luận rằng bên ngoài của nó x (được trả về từ hàm) có phạm vi mở rộng bên trong LINQ Query.

+1

Sau khi đọc tất cả các câu trả lời tôi đi đến kết luận rằng nó theo cách khác vòng. phạm vi biến bên ngoài tồn tại bên trong truy vấn LINQ. –

+1

Và một cách khác xung quanh quá ;-) Một ngôn ngữ sẽ không được tái cấu trúc thân thiện nếu nó cho phép mã biên dịch chỉ vì biến xung đột ('var x = somefunction();') là dòng thứ hai, và sau đó khi bạn di chuyển dòng thứ hai trên dòng đầu tiên, nhiều đến sự thất vọng của bạn, nó sẽ không biên dịch nữa. C# thực hiện một cơ chế trước khi làm trống, nó không cho phép 'var x = someFunction()' biên dịch ngay cả trên dòng thứ hai, vì bạn có thể nhân lại mã của bạn bất cứ lúc nào và đặt nó vào dòng đầu tiên sau này. Chúng ta đang sống trên một độ tuổi mà mã tái cấu trúc lại là chuẩn mực –

Trả lời

9

Nó không phải về LINQ về phạm vi của trẻ em.

Ví dụ:

foreach (var bar in FooBar.Bars) 
     { 
      var x = FooBar.GetFoo(); 
     } 
var x = new Foo(); 

sản xuất chính xác thông báo lỗi tương tự từ trình biên dịch.

Để khắc phục bạn chỉ cần đặt các biến trong phạm vi khác (không làm tổ). Ví dụ:

foreach (var bar in FooBar.Bars) 
     { 
      var x = FooBar.GetBar(); 
     } 
{ 
    var x = new Foo(); 
} 
4

Cho phép xem xét một cách cẩn thận,

var Foo = FoobBar.Select(x => x); 

đúng phạm vi của x kết thúc bằng sự biểu hiện

var x = somefunction() 

Bây giờ này là thú vị, điều này có phạm vi cho toàn bộ phương pháp mà giữ biểu lamda quá, do đó trình biên dịch không thể phân biệt được vì phạm vi của phần sau chồng lên nhau trước đây. và thông điệp rất nhiều thông tin quá cung cấp cho một ý nghĩa khác nhau để 'x', mà đã được sử dụng trong phạm vi một 'con'(Chọn như trong trường hợp của bạn)

Similar scope question

có lẽ bạn có thể bao gồm niềng răng xung quanh người kia để nó phạm vi được định nghĩa

{ 
var x = somefunction() 
} 
+0

Trong đoạn cuối, nó có nghĩa là phạm vi của x bị giới hạn bên trong các dấu ngoặc nhọn đó? –

+0

@NikhilAgrawal yes – V4Vendetta

1

nó không rõ ràng (để trình biên dịch) mà 'x' bạn có nghĩa là bởi thứ hai 'x' (sau khi =>).

gì nếu bạn là người viết:

var Foo = FoobBar.Select(y => x); 
var x = somefunction(); 

sau đó x trong lambda sẽ xung đột với kết quả 'SomeFunction'.

1

Bạn không thể khai báo hai biến có cùng tên trong cùng một phạm vi.

"Cùng phạm vi" có nghĩa là họ hoặc là cả hai bên trong phạm vi hiện

void method() 
{ 
    int a; 
    int a; //wrong! 
} 

hoặc một là trong hiện tại và khác là trong một phạm vi nhỏ.

void method() 
{ 
    int a; 
    for(;;) 
    { 
     int a; //wrong again! 
    } 
} 

Đây là thiết kế và giữ cho bất kỳ biến nào, từ int s đến tham chiếu lambda.

2

nghĩ nếu C# sẽ cho phép hai biến đó tồn tại trên mức độ phạm vi tương tự, điều này sẽ không thể thực hiện:

static void test() { 

    Action<int> x = (z) => { 
     Console.WriteLine(z);    
    }; 


    int[] i = { 5,2,0,1,3,1,4 }; 

    var kyrie = i.Select (x => x); 

} 

Làm thế nào bạn sẽ nói gì với C# mà bạn muốn gán các đại biểu Action tên x để Kyrie biến; hoặc ngược lại, làm thế nào bạn sẽ nói với C# bạn muốn sử dụng chính chiếu nguyên? Làm thế nào C# sẽ giải quyết điều đó?

Và độ phân giải phạm vi C# rất nhất quán cho dù bạn khai báo trước biến khác hoặc sau các biến khác, chúng đều giống nhau. ví dụ. http://www.anicehumble.com/2012/05/java-said-c-said-scope-consistency.html

Để disambiguate những kịch bản, C# không cho phép bạn để biên dịch một chương trình có tên biến mà tồn tại trên cùng một mức

Đó là tất cả về thể hiện của bạn ý định để trình biên dịch trong một không nhập nhằng cách. Và C# đã làm một công việc tốt về vấn đề đó

+0

+1 cho "Đó là tất cả về việc thể hiện ý định của bạn với trình biên dịch theo cách không mơ hồ". Chính xác. –

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