2016-11-18 19 views
6

Trong Roslyn Pattern Matching spec nó nói rằng:Pattern trận phạm vi biến

Phạm vi của một biến mô hình như sau:

Nếu mẫu xuất hiện trong điều kiện của một câu lệnh if, phạm vi của nó là điều kiện và tuyên bố được kiểm soát của câu lệnh if, nhưng không phải là mệnh đề khác của mệnh đề.

Tuy nhiên, mới nhất của Microsoft "Có gì mới" postspresentations đang hiển thị ví dụ này:

public void PrintStars(object o) 
{ 
    if (o is null) return;  // constant pattern "null" 
    if (!(o is int i)) return; // type pattern "int i" 
    WriteLine(new string('*', i)); 
} 

nào cho thấy các mô hình phù hợp i biến được sử dụng bên ngoài nếu phạm vi cấp độ của các mô hình phù hợp.

Đây có phải là sự giám sát hoặc có phạm vi được thay đổi từ thông số kỹ thuật không?

+0

Đó sẽ là tuyên bố _controlled của if statement_ – juharr

+0

@juharr, câu lệnh kiểm soát sẽ không được trả về? –

+0

Vâng, tôi đã bỏ lỡ điều đó. Tôi thực sự nghĩ rằng điều này có thể đề cập đến một 'i' ở một phạm vi cao hơn, nhưng thật khó để nói vì nó là một đoạn mã cho chức năng beta. Tôi đoán bạn có thể xem trước và thử nghiệm nó. – juharr

Trả lời

3

tôi đăng a similar question đến các vấn đề Roslyn và đã được đưa ra câu trả lời bằng cách DavidArno:

Đó là dài, nhưng bạn có thể đọc tất cả các chi tiết đẫm máu tại sao đội ngũ thiết kế ngôn ngữ đã chọn để "tăng cường" ngôn ngữ theo cách này tại #12939.

TL; DR bạn không đơn độc trong suy nghĩ thay đổi không trực quan và mâu thuẫn với cách thức phạm vi hoạt động trước đây. Nhóm buồn bã không quan tâm và thay đổi là ở đây để ở.

Có vẻ như đã quyết định rằng Phạm vi này sẽ được áp dụng, vì vậy spec tại là hết hạn, và Phạm vi này là đáng buồn ở đây để ở:

Lựa chọn 3: biến Biểu hiện được scoped bởi các câu lệnh được sử dụng, như foreach và cũng như tất cả các câu lệnh được nhúng:

Có nghĩa là một câu lệnh nhúng được sử dụng như một câu lệnh lồng nhau trong câu lệnh khác - ngoại trừ bên trong một khối. Vì vậy, các chi nhánh của một tuyên bố nếu, các cơ quan của trong khi, foreach, vv tất cả sẽ được coi là nhúng.

Hậu quả là các biến sẽ luôn thoát khỏi điều kiện của nếu, nhưng không bao giờ là các nhánh của nó. Nó giống như là bạn đặt những cuộn tròn ở tất cả các địa điểm mà bạn "phải làm".

Kết luận

Trong khi một lựa chọn ít tinh tế, chúng tôi sẽ áp dụng 3. Nó tấn công một tốt cân bằng:

Nó cho phép các kịch bản chính, bao gồm ra vars cho phi Hãy thử phương pháp, như cũng như mẫu và ra khỏi vars trong bouncer if-statements. Nó không dẫn đến đa cấp "đa" tràn lan và phản trực giác. Nó có nghĩa là bạn sẽ nhận được nhiều biến số trong phạm vi hơn chế độ hạn chế hiện tại. Điều này có vẻ không nguy hiểm, vì xác định phân tích nhiệm vụ sẽ ngăn chặn việc sử dụng uninitialized. Tuy nhiên, nó ngăn không cho các tên biến được sử dụng lại và dẫn đến các tên khác hiển thị trong danh sách hoàn thành. Điều này có vẻ như một sự cân bằng hợp lý.

2

Từ đó cùng tài liệu:

các biến được giới thiệu bởi một mô hình - tương tự như các biến ra được mô tả trước đó

Vì vậy, trên thực tế mã này:

if (!(o is int i)) return; // type pattern "int i" 

là hơn hoặc ít hơn bằng:

int i; 
if (!(SomeParsingOn(o, out i))) return; // type pattern "int i" 

Điều đó có nghĩa là i được khai báo trên cùng cấp với if, có nghĩa là nó nằm trong phạm vi không chỉ cho số if mà còn cho các tuyên bố sau. Rằng đây là sự thật có thể seens khi bạn sao chép if:

if (!(o is int i)) return; // type pattern "int i" 
if (!(o is int i)) return; // type pattern "int i" 

Cho lỗi CS0128: Một biến cục bộ có tên là 'tôi' đã được xác định trong phạm vi này.

+0

Cảm ơn bạn đã kiểm tra mã với bản xem trước! Điều này dường như mâu thuẫn với các tài liệu đặc tả, tôi sẽ tìm kiếm github cho bất kỳ đề cập đến sự thay đổi. Cá nhân tôi không thích phạm vi này vì nó không phù hợp với hầu hết các cú pháp khác, nơi các biến được định nghĩa (bắt & sử dụng). –

+1

Vâng vâng, bạn nói đúng. Điều này thật khó xử. Tôi hy vọng họ sẽ sửa chữa nó. Có lẽ nó chỉ là một lỗi, có thể là công việc đang tiến triển. –