2012-05-15 34 views
9

Khi biên dịch chương trình sau trong VS2010, VS2008 hoặc MonoDevelop trên Windows, tôi nhận cảnh báo CS0219, "Biến 'y' được gán nhưng giá trị của nó không bao giờ được sử dụng".Tại sao không có cảnh báo nào được đưa ra cho biến không sử dụng này?

namespace Problem 
{ 
    public class Program 
    {   
     private static void Main(string[] args) 
     { 
      object x = new object(); 
      int y = 0; 
     } 
    } 
} 

Tại sao không có cảnh báo cho x khi biên dịch trong Visual Studio?

Điều thú vị là, tôi nhận được cảnh báo CS0219 cho xy khi biên dịch trong MonoDevelop trên Mac OS X.

Trả lời

17

Nó chỉ ra rằng cảnh báo này bị ức chế khi cánh tay phải phía của hoạt động chuyển nhượng không phải là một thời gian biên dịch không thay đổi.

Một bài đăng bị xóa trên trang web phản hồi Visual Studio của Microsoft đã giải thích rằng đó là vì họ có rất nhiều khiếu nại từ những người đã gán biến hoàn toàn để họ có thể xem cuộc gọi phương thức được trả về trong quá trình gỡ lỗi và thấy cảnh báo kích thích:

Cuộc đàn áp của "giao nhưng không bao giờ sử dụng" cảnh báo trong trường hợp này được thúc đẩy bởi ý kiến ​​phản hồi từ những người dùng thực hiện điều này:

int Blah(){ 
    // blah 
    BlahBlah(x, y, z) 
    // blah 
    // blah 
} 

"này," nói người dùng trong khi gỡ lỗi, "tôi tự hỏi BlahBlah là gì quay lại?"Nhưng không có cách nào dễ dàng để kiểm tra giá trị trả về trong trình gỡ lỗi, vì vậy người dùng rất thường xuyên làm điều này:.

int Blah() 
{ 
    // blah 
    int temp = BlahBlah(x, y, z) 
    // blah 
    // blah 
} 

và sau đó sử dụng người dân địa phương hoặc xem cửa sổ để kiểm tra nhiệt độ Các temp là bao giờ sử dụng bất cứ nơi nào khác trong chức năng, vì vậy nó tạo ra một chất gây rát "giao nhưng không đọc" cảnh báo

tôi nghĩ rằng đây là một chút của một sự xấu hổ từ:.

  1. tôi thực sự thấy những cảnh báo này hữu ích khi chúng được đưa ra trong MonoDevelop.
  2. Bất kỳ ai cũng có thể tự ngăn chặn cảnh báo (thừa nhận rằng họ cũng sẽ loại bỏ những cảnh báo cho các phép gán không đổi thời gian biên dịch không được sử dụng - có thể có cảnh báo riêng cho điều đó?).

Dù sao, tôi hiểu rằng bạn không thể làm hài lòng tất cả mọi người.

+0

Bây giờ bạn có thể [xem giá trị trả về trong trình gỡ lỗi studio trực quan] (https://msdn.microsoft.com/en-us/library/dn323257.aspx), vẫn còn một lý do để cảnh báo này bị vô hiệu hóa không? – cloudshao

+2

Bất kỳ cách nào để bật lại cảnh báo? – Xonatron

+1

Tôi đến đây hỏi xem có ai biết cách bật lại cảnh báo ... điều này là do các nhà phát triển đang khởi tạo các biến nặng và không sử dụng chúng (nặng nề, ý tôi là tạo ra một lớp có nhiều thứ khi nó không cần thiết) –

2

tôi có thể tắt ở đây, nhưng tôi nghĩ đó là vì y chỉ được thiết lập, trong khi đó x là instantiated với một cái gì đó không tầm thường - instantiation có thể liên quan đến các hành động riêng biệt trong phương thức New(), và kể từ khi instantiating biến có thể có tác dụng phụ, nó không được coi là không sử dụng. Trong trường hợp của bạn nó chỉ là một đối tượng cơ sở(), do đó, không có tác động, nhưng có lẽ trình biên dịch không đủ thông minh để nói sự khác biệt.

Với y, mặt khác, không có tác dụng phụ cho việc khởi tạo, vì vậy nó được coi là không sử dụng - đường dẫn mã của ứng dụng sẽ không thay đổi nếu nó đã bị xóa hoàn toàn.

+1

Nhưng bạn có thể giữ lệnh gọi 'new object()' mà không gán kết quả cho biến. – phoog

2

Linh cảm của tôi là, là x một loại tham chiếu trình biên dịch không hiển thị bất kỳ cảnh báo nào vì hàm tạo có thể thực hiện một số thao tác có thể rất "có ý nghĩa"; Ngược lại, y là một loại giá trị có giá trị chỉ được gán cho nhưng không bao giờ được sử dụng, thật dễ dàng cho trình biên dịch cho bạn biết rằng không có điểm nào khi làm điều này nếu bạn không tham chiếu nó xuống dòng.

+0

Điều này có ý nghĩa, nhưng bạn nghĩ rằng trình biên dịch sẽ biết đủ để biết rằng một đối tượng hệ thống như 'đối tượng' sẽ không có tác dụng phụ. –

+1

@StevenBurnap trình biên dịch không phải là rất thông minh khi nói đến "rõ ràng" thông tin như thế. Thông thường đó là vì lợi ích của việc thêm logic để theo dõi những thứ như vậy (nhỏ) không lớn hơn chi phí phức tạp tăng của trình biên dịch (lớn). – phoog

+0

Tôi không bị thuyết phục bởi câu trả lời này. Các hiệu ứng của việc chạy trình biên dịch có thể được bảo toàn như sau: 'void Main (string [] args) {new object(); int y = 0; } '. – phoog

0

Eclipse sẽ xem xét trường hợp không được sử dụng.

1

Tính năng chia sẻ lại cũng sẽ cảnh báo bạn rằng x không được sử dụng.

0

Có thể vì x là loại tham chiếu và do đó được lưu trữ trên heap, nó sẽ ngăn chặn việc thu thập rác của đối tượng đó cho đến khi x vượt quá phạm vi.

ví dụ:

void main(string[] args) 
{ 
    object x = new object(); 
    while (true) 
    { 
     // some threading stuff 
     // x is never garbage collected 
    } 
} 

Ngược lại với:

void main(string[] args) 
{ 
    new object(); 
    while (true) 
    { 
     // some threading stuff 
     // the unreferenced object IS garbage collected 
    } 
} 
+1

AFAIK chỉ áp dụng nếu bạn đang chạy trong trình gỡ lỗi, trong trường hợp đó thời gian chạy kéo dài phạm vi sống động của người dân địa phương lên toàn bộ phương pháp. Trong chế độ phát hành, chúng có thể ngắn hơn nhiều - hoặc trong trường hợp này được loại bỏ hoàn toàn. –

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