2010-09-29 42 views
92

Tôi có tệp HTTPSystemDefinitions.cs trong dự án C#, về cơ bản mô tả các cửa sổ cũ ISAPI để sử dụng theo mã được quản lý.Ngăn chặn "không bao giờ được sử dụng" và "không bao giờ được gán cho" cảnh báo trong C#

Điều này bao gồm tập hợp đầy đủ các Cấu trúc liên quan đến ISAPI không phải tất cả hoặc được tiêu thụ theo mã. Trên biên soạn tất cả các thành viên hiện trường của các cấu trúc đang gây ra một cảnh báo như sau: -

Cảnh báo 'UnionSquare.ISAPI.HTTP_FILTER_PREPROC_HEADERS.SetHeader' Dòng không bao giờ được giao cho, và sẽ luôn luôn có giá trị null mặc định của nó

hoặc

Warning trường 'UnionSquare.ISAPI.HTTP_FILTER_PREPROC_HEADERS.HttpStatus' không bao giờ được sử dụng

Chúng có thể bị vô hiệu hóa với #pragma warning disable không? Nếu có thì số lỗi tương ứng sẽ là gì? Nếu không có bất cứ điều gì khác tôi có thể làm gì? Ghi nhớ rằng tôi chỉ làm những điều này cho tập tin này, điều quan trọng là tôi nhận được những cảnh báo như thế này đến từ các tập tin khác.

Sửa

Ví dụ struct: -

struct HTTP_FILTER_PREPROC_HEADERS 
{ 
    // 
    // For SF_NOTIFY_PREPROC_HEADERS, retrieves the specified header value. 
    // Header names should include the trailing ':'. The special values 
    // 'method', 'url' and 'version' can be used to retrieve the individual 
    // portions of the request line 
    // 

    internal GetHeaderDelegate GetHeader; 
    internal SetHeaderDelegate SetHeader; 
    internal AddHeaderDelegate AddHeader; 

    UInt32 HttpStatus;    // New in 4.0, status for SEND_RESPONSE 
    UInt32 dwReserved;    // New in 4.0 
} 
+0

Bạn có thể hiển thị khai báo các trường đó hay đúng hơn là cấu trúc của chúng? I E. cho một ví dụ. –

+0

@Lasse: Đã thêm ví dụ. – AnthonyWJones

+8

Nếu đây là các định nghĩa interop, thì thông thường bạn sẽ đặt '[StructLayout (LayoutKind.Sequential)]' để đảm bảo bố trí bộ nhớ là chính xác (trong triển khai hiện tại nó sẽ không có thuộc tính này, nhưng AFAIK nó không được bảo đảm). Nếu tôi nhớ chính xác, trình biên dịch C# phát hiện sự hiện diện của thuộc tính này và tự động loại bỏ các cảnh báo đó vì nó biết các trường phải ở đó cho interop. (Tôi có thể sai về điều này, do đó đăng tải dưới dạng bình luận thay vì trả lời). –

Trả lời

164

Vâng, chúng có thể bị dập tắt.

Thông thường, tôi phản đối việc ngăn chặn cảnh báo, nhưng trong trường hợp này, cấu trúc được sử dụng cho interop hoàn toàn yêu cầu phải có một số trường, mặc dù bạn không bao giờ có ý định sử dụng chúng. nó phải được biện minh.

Thông thường, để chặn hai cảnh báo đó, bạn sẽ sửa mã vi phạm. Việc đầu tiên ("... không bao giờ được sử dụng") thường là một mã của mùi thức ăn thừa từ các phiên bản trước của mã. Có lẽ mã đã bị xóa, nhưng các trường bị bỏ lại phía sau.

Thông tin thứ hai thường là mã dành cho các trường được sử dụng không chính xác. Ví dụ, bạn có thể viết sai giá trị mới của một thuộc tính trở lại chính bản thân nó, không bao giờ viết vào trường sao lưu.


Để ngăn chặn cảnh báo cho "Dòng XYZ không bao giờ được sử dụng", bạn làm như sau:

#pragma warning disable 0169 
... field declaration 
#pragma warning restore 0169 

Để ngăn chặn cảnh báo cho "Dòng XYZ không bao giờ được giao cho, và sẽ luôn luôn có nó giá trị mặc định XX ", bạn thực hiện việc này:

#pragma warning disable 0649 
... field declaration 
#pragma warning restore 0649 

Để tìm số tự cảnh báo như vậy (ví dụ:làm thế nào mà tôi biết để sử dụng 0169 và 0649), bạn làm như sau:

  • Biên dịch mã như bình thường, điều này sẽ thêm một số cảnh báo vào danh sách lỗi của bạn trong Visual Studio
  • Chuyển sang cửa sổ Output, và xây dựng đầu ra, và săn lùng những lời cảnh báo tương tự
  • Sao chép mã cảnh báo 4 chữ số từ thông điệp có liên quan, mà nên xem xét như thế này:

    C: \ Dev \ VS.NET \ ConsoleApplication19 \ ConsoleApplication19 \ Program.cs (10,28): cảnh báo CS : Dòng 'ConsoleApplication19.Program.dwReserved' không bao giờ là giao cho, và sẽ luôn luôn có giá trị mặc định của nó 0


Caveat: Theo nhận xét của @Jon Hanna, có lẽ một vài cảnh báo là để cho điều này, cho người tìm tương lai của câu hỏi và câu trả lời này.

  • Đầu tiên, và quan trọng nhất, hành động ngăn chặn cảnh báo cũng giống như nuốt thuốc khi đau đầu. Chắc chắn, nó có thể là điều phải làm đôi khi, nhưng nó không phải là một giải pháp bắt tất cả. Đôi khi, đau đầu là một triệu chứng thực sự mà bạn không nên che mặt, cùng với cảnh báo. Nó luôn luôn là tốt nhất để cố gắng để điều trị các cảnh báo bằng cách sửa chữa nguyên nhân của họ, thay vì chỉ một cách mù quáng loại bỏ chúng từ đầu ra xây dựng.
  • Có nói rằng, nếu bạn cần chặn cảnh báo, hãy làm theo mẫu tôi đã nêu ở trên. Dòng mã đầu tiên, #pragma warning disable XYZK, tắt cảnh báo cho phần còn lại của tệp đó hoặc ít nhất là cho đến khi tìm thấy #pragma warning restore XYZK tương ứng. Giảm thiểu số lượng dòng bạn vô hiệu hóa các cảnh báo này. Mẫu ở trên vô hiệu hóa cảnh báo cho chỉ một dòng.
  • Ngoài ra, như Jon đề cập, một nhận xét về lý do tại sao bạn làm điều này là một ý tưởng hay. Vô hiệu hóa cảnh báo chắc chắn là một mã code khi được thực hiện mà không có nguyên nhân và nhận xét sẽ ngăn người bảo trì trong tương lai dành thời gian hoặc tự hỏi tại sao bạn làm điều đó hoặc thậm chí bằng cách xóa nó và cố gắng sửa các cảnh báo.
+0

Điều này thật tuyệt vời để biết! –

+8

Tôi khuyên bạn nên tiếp tục với câu trả lời ở trên, phạm vi của việc vô hiệu hóa càng nhỏ càng tốt (để tránh vô hiệu hóa nó ở nơi nào đó hữu ích) và luôn đi kèm với việc vô hiệu hóa với nhận xét về lý do bạn vô hiệu hóa, ví dụ: '// tồn tại cho interop' trong trường hợp này. –

+0

Đó là lời khuyên tốt @ Jon, tôi hết lòng đồng ý. –

4

Tôi đã VS tạo bộ khung triển khai cho System.ComponentModel.INotifyPropertyChanged và các sự kiện được triển khai dưới dạng các trường đã kích hoạt cảnh báo CS0067.

Là giải pháp thay thế cho câu trả lời được chấp nhận Tôi đã chuyển đổi trường thành thuộc tính và cảnh báo biến mất. Điều này có ý nghĩa vì đường cú pháp khai báo thuộc tính được biên dịch thành một trường cộng với phương thức getter và/hoặc setter (thêm/xóa trong trường hợp của tôi) tham chiếu đến trường này. Điều này thỏa mãn trình biên dịch và các cảnh báo không được nâng lên:

struct HTTP_FILTER_PREPROC_HEADERS 
{ 
    // 
    // For SF_NOTIFY_PREPROC_HEADERS, retrieves the specified header value. 
    // Header names should include the trailing ':'. The special values 
    // 'method', 'url' and 'version' can be used to retrieve the individual 
    // portions of the request line 
    // 

    internal GetHeaderDelegate GetHeader {get;set;} 
    internal SetHeaderDelegate SetHeader { get; set; } 
    internal AddHeaderDelegate AddHeader { get; set; } 

    UInt32 HttpStatus { get; set; }    // New in 4.0, status for SEND_RESPONSE 
    UInt32 dwReserved { get; set; }    // New in 4.0 
} 
+0

Giải pháp của bạn duyên dáng hơn nhiều so với vô hiệu hóa cảnh báo, nhưng nó có thể ảnh hưởng đến một số thuộc tính chỉ dành cho trường, ví dụ: MarshalAsAttribute. – HuBeZa

+0

Thông tin: Các trường riêng tư thực tế được tạo trong tình huống này có thể có các tên "lạ" như ' k__BackingField', tùy thuộc vào chi tiết triển khai của trình biên dịch C# được sử dụng. –

11

Một "giải pháp" khác để khắc phục những cảnh báo này là tạo cấu trúc public. Các cảnh báo không được ban hành sau đó bởi vì trình biên dịch không thể biết liệu các trường đang được sử dụng (được gán) bên ngoài assembly hay không.

Điều đó cho biết, các thành phần "interop" thường không được công khai, mà là internal hoặc private.

+0

Tốt, điều này sẽ ẩn cảnh báo… nhưng việc thiết lập 'cấu trúc' như 'công khai' có thể là sai lầm hơn so với cảnh báo mà chúng tôi đang cố gắng che dấu. (Có thể bạn không nên để lộ các loại không cần thiết được sử dụng để triển khai nội bộ và các loại có trường công khai có thể không thuộc về API công khai). Chỉ cần để củng cố lời khuyên của bạn rằng các loại như vậy nên được "thay vì' nội bộ' hoặc 'riêng'" ;-). – binki

1

Người dùng C/C++ có (void)var; để chặn cảnh báo biến không sử dụng. Tôi chỉ phát hiện ra bạn cũng có thể ngăn chặn các biến cảnh báo không sử dụng trong C# với toán tử Bitwise:

 uint test1 = 12345; 
     test1 |= 0; // test1 is still 12345 

     bool test2 = true; 
     test2 &= false; // test2 is now false 

Cả hai biểu thức không tạo ra các cảnh báo biến không sử dụng trong VS2010 C# 4.0 và Mono 2.10 trình biên dịch.

+2

Làm việc cho 'uint', nhưng không phải cho các loại khác, như là 'Ngoại lệ'. Bạn có biết một mẹo chung tương đương với C/C++ 'var;'? – manuell

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