2017-01-03 12 views
17

Tôi đã nâng cấp dự án của mình để nhắm mục tiêu C# 7 và sử dụng Visual Studio 2017 RC để triển khai khớp mẫu trên giải pháp của tôi. Sau khi thực hiện điều này, một số lỗi đã được giới thiệu liên quan đến mẫu khớp với các tham số chung.Biểu thức loại T không thể xử lý theo kiểu X

Xét đoạn mã sau:

public class Packet 
{ 
} 

public class KeepalivePacket : Packet 
{ 
} 

public void Send<T>(T packet) 
    where T : Packet 
{ 
    if (packet is KeepalivePacket keepalive) 
    { 
     // Do stuff with keepalive 
    } 

    switch (packet) 
    { 
     case KeepalivePacket keepalivePacket: 
      // Do stuff with keepalivePacket 
      break; 
    } 
} 

Cả if tuyên bố và case tuyên bố tạo ra một lỗi biên dịch.

Một biểu hiện của loại T không thể được xử lý bởi một mô hình của loại KeepalivePacket

Nếu tôi lần đầu tiên diễn viên tham số để gõ object mô hình phù hợp với các công trình như mong đợi. Roslyn sau đó đánh dấu diễn viên là object là dư thừa.

if ((object)packet is KeepalivePacket keepalive) 
{ 
    // This works 
} 

Lỗi này chỉ xuất hiện để áp dụng cho các tham số và biến chung. Roslyn dường như không nhận thức được vấn đề này vì nó khuyến nghị thay đổi mã để sử dụng đối sánh mẫu thông qua một trình phân tích và cho phép tôi áp dụng "sửa mã" dẫn đến mã bị hỏng.

+0

Dường như * thiết kế xấu * nếu bạn phải bật loại đối tượng. Trên thực tế toán tử 'is' là một số đã được coi là * mùi hôi * ... –

+3

@WillemVanOnsem phải có đủ trường hợp sử dụng để khớp mẫu cho nhóm C# để thêm nó vào đặc tả, phải không? –

+0

thực sự, đơn giản bởi vì trong hầu hết các ứng dụng công nghiệp, người ta không thể thiết kế toàn bộ điều đầu tiên: nó quá phức tạp. Nhưng thực tế tất cả các toán tử 'is', vv được thay thế tốt hơn bởi các ràng buộc động, vì chúng có nhiều an toàn hơn. –

Trả lời

12

Như explained by Neal Gafter từ Microsoft:

Lý do nó không hoạt động là không có chuyển đổi (rõ ràng hoặc ngầm) được xác định từ T để KeepalivePacket. Kết hợp mẫu yêu cầu một chuyển đổi như vậy tồn tại, vì nó được định nghĩa theo thuật toán toán tử, yêu cầu chuyển đổi tồn tại. Đặc tả ngôn ngữ và trình biên dịch đồng ý rằng không có chuyển đổi nào tồn tại. Có vẻ lạ với tôi rằng đặc tả ngôn ngữ được định nghĩa sao cho không có chuyển đổi (rõ ràng) tồn tại ở đây. Chúng ta sẽ xem xét những gì chúng ta có thể làm.

Chúng tôi sẽ không làm bất cứ điều gì về điều này trong C# 7. Bạn sẽ phải thêm một diễn viên vào mã của bạn để làm việc xung quanh nó. Khi chúng ta có các mẫu đệ quy, điều này có thể khó khăn hơn để làm việc xung quanh. Hơn nữa, quy tắc ngôn ngữ khó xử làm nền tảng cho vấn đề này (tức là không có sự chuyển đổi từ T thành KeepalivePacket) không có ý nghĩa gì nhiều.

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