การระงับคำเตือน "ไม่เคยใช้" และ "ไม่เคยถูกกำหนดให้" ใน C #


107

ฉันมีไฟล์ HTTPSystemDefinitions.cs ในโครงการ C # ซึ่งโดยพื้นฐานแล้วจะอธิบายถึง ISAPI ของ windows รุ่นเก่าสำหรับการใช้งานโดยใช้รหัสที่มีการจัดการ

ซึ่งรวมถึงชุดโครงสร้างทั้งหมดที่เกี่ยวข้องกับ ISAPI ซึ่งไม่ใช่ทั้งหมดหรือถูกใช้โดยรหัส ในการคอมไพล์สมาชิกฟิลด์ทั้งหมดของโครงสร้างเหล่านี้ทำให้เกิดคำเตือนดังต่อไปนี้: -

ฟิลด์คำเตือน 'UnionSquare.ISAPI.HTTP_FILTER_PREPROC_HEADERS.SetHeader' จะไม่ถูกกำหนดให้และจะมีค่าเริ่มต้นเป็นค่าว่างเสมอ

หรือ

คำเตือนไม่ใช้ฟิลด์ 'UnionSquare.ISAPI.HTTP_FILTER_PREPROC_HEADERS.HttpStatus'

สิ่งเหล่านี้สามารถปิดการใช้งานได้#pragma warning disableหรือไม่? ถ้าเป็นเช่นนั้นตัวเลขข้อผิดพลาดที่เกี่ยวข้องจะเป็นอย่างไร ถ้าไม่มีฉันสามารถทำอะไรได้อีก? โปรดทราบว่าฉันจะทำสิ่งนี้สำหรับไฟล์นี้เท่านั้นสิ่งสำคัญคือฉันจะได้รับคำเตือนเช่นนี้มาจากไฟล์อื่น ๆ

แก้ไข

ตัวอย่างโครงสร้าง: -

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
}

คุณสามารถแสดงการประกาศของฟิลด์เหล่านั้นหรือมากกว่าโครงสร้างที่อยู่ใน? กล่าวคือ. ยกตัวอย่าง.
Lasse V.Karlsen

11
หากสิ่งเหล่านี้เป็นคำจำกัดความของการทำงานร่วมกันตามปกติคุณจะ[StructLayout(LayoutKind.Sequential)]ต้องแน่ใจว่าเค้าโครงหน่วยความจำถูกต้อง (ในการใช้งานปัจจุบันจะไม่มีแอตทริบิวต์นี้ แต่ไม่รับประกัน AFAIK) ถ้าฉันจำไม่ผิดคอมไพเลอร์ C # จะตรวจพบการมีอยู่ของแอตทริบิวต์นี้และระงับคำเตือนเหล่านั้นโดยอัตโนมัติเนื่องจากทราบว่าต้องมีช่องสำหรับการทำงานร่วมกัน (ฉันอาจจะผิดเกี่ยวกับเรื่องนี้ดังนั้นการโพสต์เป็นความคิดเห็นแทนที่จะเป็นคำตอบ)
Greg Beech

@Greg: นั่นเป็นข้อมูลที่มีประโยชน์ฉันจะตรวจสอบฉันไม่อยากให้เกิดคำเตือนแทนที่จะระงับ
AnthonyWJones

1
+1 StructLayoutสำหรับใช้ ดูเหมือนสะอาดกว่าการระงับคำเตือนด้วยตนเอง
เดียร์น่า

@GregBeech คุณพูดถูก! ที่ยังคงใช้สำหรับโครงการ. NET Standard ใน VS2017
zwcloud

คำตอบ:


195

ใช่สิ่งเหล่านี้สามารถระงับได้

โดยปกติฉันไม่เห็นด้วยกับการระงับคำเตือน แต่ในกรณีนี้โครงสร้างที่ใช้สำหรับการทำงานร่วมกันจำเป็นต้องมีฟิลด์บางช่องอยู่แม้ว่าคุณจะไม่เคย (หรือสามารถ) ใช้ก็ตามดังนั้นในกรณีนี้ฉันคิดว่ามันควรจะเป็นธรรม .

โดยปกติหากต้องการระงับคำเตือนทั้งสองนี้คุณจะต้องแก้ไขรหัสที่ละเมิด อันแรก ("... ไม่เคยใช้") มักจะเป็นรหัสกลิ่นของของเหลือจากโค้ดเวอร์ชันก่อนหน้า บางทีรหัสอาจถูกลบ แต่ช่องถูกทิ้งไว้

อย่างที่สองมักจะเป็นกลิ่นรหัสสำหรับฟิลด์ที่ใช้ไม่ถูกต้อง ตัวอย่างเช่นคุณอาจเขียนค่าใหม่ของคุณสมบัติกลับไปยังคุณสมบัติไม่ถูกต้องอย่าเขียนลงในช่องสำรอง


ในการระงับคำเตือนสำหรับ " Field XYZ is never used " ให้ดำเนินการดังนี้:

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

ในการระงับคำเตือนสำหรับ " ไม่เคยกำหนดฟิลด์ XYZ ให้และจะมีค่าเริ่มต้นเป็น XX เสมอ " ให้ดำเนินการดังนี้:

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

หากต้องการค้นหาหมายเลขเตือนดังกล่าวด้วยตัวคุณเอง (เช่นฉันรู้ได้อย่างไรว่าจะใช้ 0169 และ 0649) ให้ทำสิ่งนี้:

  • คอมไพล์โค้ดตามปกติซึ่งจะเพิ่มคำเตือนในรายการข้อผิดพลาดของคุณใน Visual Studio
  • สลับไปที่หน้าต่างเอาต์พุตและเอาต์พุตของบิลด์และค้นหาคำเตือนเดียวกัน
  • คัดลอกรหัสคำเตือน 4 หลักจากข้อความที่เกี่ยวข้องซึ่งควรมีลักษณะดังนี้:

    C: \ Dev \ VS.NET \ ConsoleApplication19 \ ConsoleApplication19 \ Program.cs (10,28): คำเตือน CS 0649 : ฟิลด์ 'ConsoleApplication19.Program.dwReserved' จะไม่ถูกกำหนดให้และจะมีค่าเริ่มต้นเป็น 0 เสมอ


ข้อแม้ : ตามความคิดเห็นของ@ จอนฮันนาอาจมีคำเตือนบางประการสำหรับสิ่งนี้สำหรับผู้ค้นหาคำถามและคำตอบนี้ในอนาคต

  • ประการแรกและสำคัญที่สุดการระงับคำเตือนนั้นคล้ายกับการกลืนยาเพื่อปวดศีรษะ แน่นอนว่าบางครั้งอาจเป็นสิ่งที่ถูกต้อง แต่ก็ไม่ใช่วิธีแก้ปัญหาทั้งหมด บางครั้งอาการปวดหัวเป็นอาการที่แท้จริงที่คุณไม่ควรปิดบังเช่นเดียวกับคำเตือน ทางที่ดีที่สุดคือพยายามรักษาคำเตือนโดยการแก้ไขสาเหตุแทนที่จะลบออกจากเอาต์พุตบิลด์แบบสุ่มสี่สุ่มห้า
  • ต้องบอกว่าหากคุณต้องการระงับคำเตือนให้ทำตามรูปแบบที่ฉันวางไว้ข้างต้น บรรทัดรหัสแรก#pragma warning disable XYZKปิดใช้งานคำเตือนสำหรับส่วนที่เหลือของไฟล์นั้นหรืออย่างน้อยก็จนกว่า#pragma warning restore XYZKจะพบสิ่งที่เกี่ยวข้อง ลดจำนวนบรรทัดที่คุณปิดใช้งานคำเตือนเหล่านี้ รูปแบบด้านบนปิดใช้งานคำเตือนเพียงบรรทัดเดียว
  • ตามที่จอนพูดถึงความคิดเห็นว่าทำไมคุณถึงทำสิ่งนี้เป็นความคิดที่ดี การปิดใช้งานคำเตือนนั้นเป็นเพียงกลิ่นรหัสเมื่อทำโดยไม่มีสาเหตุและความคิดเห็นจะป้องกันไม่ให้ผู้ดูแลในอนาคตใช้เวลาสงสัยว่าทำไมคุณถึงทำเช่นนั้นหรือแม้กระทั่งการลบคำเตือนและพยายามแก้ไขคำเตือน

9
ฉันขอแนะนำเพิ่มเติมสำหรับคำตอบข้างต้นว่าขอบเขตของการปิดใช้งานมีขนาดเล็กที่สุดเท่าที่จะเป็นไปได้ (เพื่อหลีกเลี่ยงการปิดการใช้งานในที่ที่มีประโยชน์) และให้มาพร้อมกับการปิดใช้งานพร้อมกับความคิดเห็นเสมอว่าเหตุใดคุณจึงปิดใช้งานเช่น//exists for interopใน กรณีนี้.
Jon Hanna

ขอบคุณมาก. เป็นตัวเลือกแปลก ๆ ที่ VS ไม่มีคอลัมน์สำหรับตัวเลขเหล่านี้ในหน้าต่างรายการข้อผิดพลาด
AnthonyWJones

2
ดังที่จอนกล่าวการแสดงความคิดเห็นว่า "ทำไม" จึงมีความสำคัญมาก นอกจากนี้ฉันมักจะเพิ่มข้อความอย่างน้อยส่วนหนึ่งของข้อความเตือนในความคิดเห็นเช่น // Suppress "ไม่เคยกำหนดให้ ... " คำเตือน ช่วยให้ผู้ดูแลรักษาในอนาคตต้องรำคาญที่ต้องค้นหารหัสคำเตือนเพราะอาจเป็นคุณ!
Tom Bushell

1
มันไม่ชัดเจนในทันที แต่คุณสามารถใช้ค้นหาในหน้าต่างผลลัพธ์ผ่าน CTRL + F พิมพ์ "คำเตือน" คลิก "ค้นหาทั้งหมด" และรับคำเตือนทุกคำเตือนอย่างรวดเร็วพร้อมตัวเลขเตือนที่แสดง ที่กล่าวว่า[StructLayout(LayoutKind.Sequential)]แอตทริบิวต์จัดการ interop ได้ดีขึ้นมากตามความคิดเห็นของ Greg Beech ในคำถาม
Ryan Buddicom

2
แสดงความคิดเห็นว่าสำหรับผู้ใช้ Unity3D หมายเลขคำเตือนคือ 0414 สำหรับฟิลด์ส่วนตัวและ 0219 สำหรับตัวแปรโลคัลไม่ใช่ 169 (ซึ่งแสดงคำเตือนว่าไม่สามารถเรียกคืนคำเตือนแทนได้)
Draco18s ไม่ไว้วางใจ SE

14

อีก "การแก้ปัญหา" เพื่อแก้ไขคำเตือนเหล่านี้คือโดยการที่ publicstruct คำเตือนจะไม่ออกเนื่องจากคอมไพเลอร์ไม่สามารถทราบได้ว่ามีการใช้ฟิลด์ (กำหนด) นอกแอสเซมบลีหรือไม่

ที่กล่าวว่า "การทำงานร่วมกัน" ส่วนประกอบควรมักจะไม่เป็นสาธารณะ แต่หรือinternalprivate


2
นีซนี้จะซ่อนคำเตือน ... แต่การตั้งค่าดังกล่าวstructเป็นpublicมีแนวโน้มที่จะเป็นความผิดพลาดมากกว่าคำเตือนที่เรากำลังพยายามที่จะปกปิด (คุณอาจไม่ควรเปิดเผยประเภทที่ใช้สำหรับการใช้งานภายในโดยไม่จำเป็นและประเภทที่มีฟิลด์สาธารณะอาจไม่อยู่ใน API สาธารณะ) เพียงเพื่อตอกย้ำคำแนะนำของคุณว่าควรเป็นประเภท "มากกว่าinternalหรือprivate" ;-)
binki

ขอบคุณมาก - นี่คือสิ่งที่ฉันต้องการ ฉันกำลังใช้JsonConvert.DeserializeObjectและฉันกำลังแยกออกเป็นคลาสสาธารณะที่มีคุณสมบัติทั้งหมดที่เปิดเผยเพื่อที่ฉันจะได้รู้ว่าจะได้อะไรกลับมา เพียงแค่ทำให้เป็นคลาสสาธารณะที่ว่างเปล่าโดยมีสตริงสาธารณะทั้งหมดเป็นโค้ดสั้น ๆ ที่ดีและตอนนี้ไม่มีคำเตือนอีกต่อไป บางทีการใช้คลาสไดนามิกจะดีกว่าเนื่องจากคุณไม่จำเป็นต้องระบุอย่างชัดเจนว่ามีอะไรอยู่ในอาร์เรย์ แต่ฉันคิดว่านี่จะเป็นการอ้างอิงที่ดีสำหรับทุกคนที่ต้องการใช้ออบเจ็กต์
user1274820

6

ฉันได้ VS เพื่อสร้างโครงกระดูกการนำไปใช้System.ComponentModel.INotifyPropertyChangedและเหตุการณ์ถูกนำไปใช้เป็นฟิลด์ที่เรียกใช้คำเตือน CS0067

เป็นทางเลือกหนึ่งของโซลูชันที่ให้ไว้ในคำตอบที่ยอมรับฉันแปลงฟิลด์เป็นคุณสมบัติและคำเตือนก็หายไปฉันแปลงเขตข้อมูลลงในคุณสมบัติและเตือนหายไป

สิ่งนี้สมเหตุสมผลเนื่องจากไวยากรณ์การประกาศคุณสมบัติน้ำตาลถูกคอมไพล์เป็นฟิลด์บวก getter และ / หรือเมธอด setter (เพิ่ม / ลบในกรณีของฉัน) ซึ่งอ้างอิงฟิลด์ สิ่งนี้เป็นไปตามคอมไพเลอร์และคำเตือนจะไม่ขึ้น:

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
}

วิธีการแก้ปัญหาของคุณมีความสง่างามกว่าการปิดใช้งานคำเตือน แต่อาจรบกวนคุณลักษณะเฉพาะฟิลด์บางอย่างเช่น MarshalAsAttribute
HuBeZa

1
ข้อมูล: ฟิลด์ส่วนตัวจริงที่สร้างขึ้นในสถานการณ์นี้อาจมีชื่อ "แปลก ๆ " เช่น<GetHeader>k__BackingFieldขึ้นอยู่กับรายละเอียดการใช้งานของคอมไพเลอร์ C # ที่ใช้
Jeppe Stig Nielsen

1

ผู้ใช้ C / C ++ ต้อง(void)var;ระงับคำเตือนตัวแปรที่ไม่ได้ใช้ ฉันเพิ่งค้นพบว่าคุณสามารถระงับคำเตือนตัวแปรที่ไม่ได้ใช้ใน C # ด้วยตัวดำเนินการแบบบิต:

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

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

นิพจน์ทั้งสองไม่สร้างคำเตือนตัวแปรที่ไม่ได้ใช้ในคอมไพเลอร์ VS2010 C # 4.0 และ Mono 2.10


4
ใช้ได้กับuintแต่ไม่ใช่สำหรับประเภทอื่นเช่นException. คุณรู้เคล็ดลับทั่วไปที่เทียบเท่ากับ C / C ++ var;หรือไม่?
manuell

1
@manuell สวัสดีจากอนาคต! คุณสามารถใช้error.ToString();สำหรับตัวแปรประเภทException
Sv443

ขอบคุณจากตอนนี้ เคล็ดลับนั้นเพิ่มโค้ดจริงที่รันไทม์ใช่ไหม?
manuell
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.