วิธีที่ดีที่สุดในการทำเครื่องหมายวิธีการที่เรียกว่าผ่านการสะท้อน?


11

ซอฟต์แวร์ของเรามีหลายคลาสที่ควรพบแบบไดนามิกผ่านการสะท้อนกลับ คลาสทั้งหมดมีคอนสตรัคเตอร์ที่มีลายเซ็นเฉพาะซึ่งรหัสการสะท้อนจะทำให้วัตถุเป็นอินสแตนซ์
อย่างไรก็ตามเมื่อมีคนตรวจสอบว่ามีการอ้างอิงวิธีการนั้นหรือไม่ (เช่นผ่าน Visual Studio Code Lens) การอ้างอิงผ่านการสะท้อนกลับจะไม่ถูกนับ ผู้คนสามารถพลาดการอ้างอิงและลบ (หรือเปลี่ยน) วิธีที่ไม่ได้ใช้อย่างเห็นได้ชัด

เราควรทำเครื่องหมาย / วิธีการเอกสารที่ต้องการเรียกผ่านการสะท้อนอย่างไร

เป็นการดีที่ควรทำเครื่องหมายวิธีในลักษณะที่ทั้งเพื่อนร่วมงานและ Visual Studio / Roslyn และเครื่องมืออัตโนมัติอื่น ๆ 'ดู' ว่าวิธีการมีวัตถุประสงค์ที่จะเรียกว่าผ่านการสะท้อน

ฉันรู้ว่ามีสองตัวเลือกที่เราสามารถใช้ได้ แต่ทั้งคู่ไม่ค่อยพอใจ เนื่องจาก Visual Studio ไม่พบการอ้างอิง:

  • ใช้แอตทริบิวต์ที่กำหนดเองและทำเครื่องหมายตัวสร้างด้วยคุณลักษณะนี้
    • ปัญหาคือคุณสมบัติของแอททริบิวไม่สามารถเป็นการอ้างอิงเมธอดได้ดังนั้นตัวสร้างจะยังคงแสดงว่ามีการอ้างอิง 0 รายการ
    • เพื่อนร่วมงานที่ไม่คุ้นเคยกับแอตทริบิวต์ที่กำหนดเองอาจจะเพิกเฉย
    • ข้อดีของวิธีการปัจจุบันของฉันคือส่วนการสะท้อนสามารถใช้คุณลักษณะเพื่อค้นหาตัวสร้างที่ควรเรียกใช้
  • ใช้ความคิดเห็นเพื่อจัดทำเอกสารว่าเมธอด / คอนสตรัคเตอร์ตั้งใจที่จะเรียกผ่านการสะท้อนกลับ
    • เครื่องมืออัตโนมัติไม่สนใจความคิดเห็น (และเพื่อนร่วมงานก็ทำได้เช่นกัน)
    • ความคิดเห็นเกี่ยวกับเอกสาร XMLสามารถนำมาใช้เพื่อให้ Visual Studio นับการอ้างอิงเพิ่มเติมถึงวิธีการ / คอนสตรัคเตอร์:
      อนุญาตให้MyPluginคลาสที่ตัวสร้างเรียกใช้ผ่านการสะท้อนกลับ สมมติว่าโค้ดการสะท้อนที่กล่าวอ้างค้นหาคอนสตรัคเตอร์ที่รับintพารามิเตอร์ เอกสารประกอบต่อไปนี้ทำให้เลนส์รหัสแสดงคอนสตรัคเตอร์ที่มีการอ้างอิง 1 รายการ:
      /// <see cref="MyPlugin.MyPlugin(int)"/> is invoked via reflection

มีตัวเลือกไหนดีกว่ากัน?
แนวปฏิบัติที่ดีที่สุดสำหรับการทำเครื่องหมายวิธี / คอนสตรัคเตอร์ที่ตั้งใจจะเรียกผ่านการสะท้อนคืออะไร


เพื่อให้ชัดเจนนี่คือระบบปลั๊กอินบางประเภทใช่มั้ย
whatsisname

2
คุณคิดว่าเพื่อนร่วมงานของคุณจะเพิกเฉยหรือพลาดทุกสิ่งที่คุณทำ ... คุณไม่สามารถป้องกันรหัสจากการทำงานที่ไม่มีประสิทธิภาพเช่นนั้นได้ การทำเอกสารดูเหมือนจะเป็นวิธีที่ง่ายขึ้นสะอาดขึ้นถูกกว่าและแนะนำให้เลือก มิฉะนั้นจะไม่มีการเขียนโปรแกรมที่เปิดเผย
Laiv

1
Resharper มีแอตทริบิวต์ [UsedImplictly]
CodesInChaos

4
ฉันเดาตัวเลือกความคิดเห็น doc XML เป็นตัวเลือกที่ดีที่สุดของคุณ มันสั้นเอกสารด้วยตนเองและไม่จำเป็นต้องมี "แฮ็ก" หรือคำจำกัดความเพิ่มเติม
Doc Brown

2
โหวตอีกครั้งสำหรับความคิดเห็นเอกสาร xml หากคุณกำลังสร้างเอกสารอยู่ดีมันควรจะโดดเด่นในเอกสารที่สร้างขึ้น
Frank Hileman

คำตอบ:


12

การรวมกันของโซลูชั่นที่แนะนำ:

  • ใช้แท็กเอกสาร XML เพื่อทำเอกสารว่าคอนสตรัคเตอร์ / วิธีการถูกเรียกผ่านการสะท้อนกลับ
    สิ่งนี้ควรอธิบายการใช้งานที่ตั้งใจไว้ให้กับเพื่อนร่วมงาน (และตัวฉันในอนาคต)
  • ใช้ 'เคล็ดลับ' ผ่านทาง<see>-tag เพื่อเพิ่มจำนวนการอ้างอิงสำหรับตัวสร้าง / วิธี
    สิ่งนี้ทำให้เลนส์รหัสนั้นและการค้นหาอ้างอิงแสดงว่ามีการอ้างอิง Constructor / Method
  • ใส่คำอธิบายประกอบกับ Resharper's UsedImplicitlyAttribute
    • Resharper เป็นมาตรฐานอย่างแท้จริงและ[UsedImplicitly]มีความหมายที่ตั้งใจไว้อย่างแม่นยำ
    • ผู้ที่ไม่ได้ใช้ Resharper สามารถติดตั้งJetBrains ReSharper คำอธิบายประกอบผ่าน NuGet: PM>
      Install-Package JetBrains.Annotations
  • ถ้ามันเป็นวิธีการที่ภาคเอกชนและคุณกำลังใช้ Visual วิเคราะห์รหัสสตูดิโอของใช้สำหรับข้อความSupressMessageAttribute CA1811: Avoid uncalled private code

ตัวอย่างเช่น:

class MyPlugin
{
    /// <remarks>
    /// <see cref="MyPlugin.MyPlugin(int)"/> is called via reflection.
    /// </remarks>
    [JetBrains.Annotations.UsedImplicitly]
    public MyPlugin(int arg)
    {
        throw new NotImplementedException();
    }

    /// <remarks>
    /// <see cref="MyPlugin.MyPlugin(string)"/> is called via reflection.
    /// </remarks>
    [JetBrains.Annotations.UsedImplicitly]
    [System.Diagnostics.CodeAnalysis.SuppressMessage(
        "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode",
        Justification = "Constructor is called via reflection")]
    private MyPlugin(string arg)
    {
        throw new NotImplementedException();
    }
}

วิธีการแก้ปัญหาการใช้งานที่สร้างขึ้นของทั้งผู้อ่านของมนุษย์และระบบการวิเคราะห์รหัสแบบคงที่ 3 ส่วนใหญ่ที่ใช้กับ C # และ Visual Studio
ข้อเสียคือทั้งความคิดเห็นและคำอธิบายประกอบหนึ่งหรือสองอาจดูเหมือนซ้ำซ้อนเล็กน้อย


โปรดทราบว่ายังมีMeansImplicitUseAttributeที่สามารถใช้เพื่อสร้างคุณลักษณะของคุณเองที่มีUsedImplicitlyผลกระทบ สิ่งนี้สามารถลดเสียงรบกวนของคุณลักษณะในสถานการณ์ที่เหมาะสม
Dave Cousineau

ลิงก์ไปยัง JetBrains ใช้งานไม่ได้
John Zabroski

5

ฉันไม่เคยมีปัญหานี้ในโครงการ. Net แต่ฉันมีปัญหาเดียวกันกับโครงการ Java เป็นประจำ วิธีการตามปกติของฉันคือการใช้@SuppressWarnings("unused")คำอธิบายประกอบที่เพิ่มความคิดเห็นอธิบายว่าทำไม (การบันทึกเหตุผลของการปิดใช้งานคำเตือนใด ๆ เป็นส่วนหนึ่งของรูปแบบรหัสมาตรฐานของฉัน - เมื่อใดก็ตามที่คอมไพเลอร์ไม่สามารถเข้าใจได้ เกินไป). นี่เป็นข้อได้เปรียบของการทำให้มั่นใจได้ว่าเครื่องมือวิเคราะห์แบบคงที่จะทราบว่ารหัสไม่ควรมีการอ้างอิงโดยตรงและให้เหตุผลโดยละเอียดสำหรับผู้อ่านที่เป็นมนุษย์

C # เทียบเท่าของ Java มี@SuppressWarnings SuppressMessageAttributeสำหรับส่วนตัววิธีการที่คุณสามารถใช้ข้อความCA1811: หลีกเลี่ยงไม่ได้เรียกรหัสส่วนตัว ; เช่น:

class MyPlugin
{
    [System.Diagnostics.CodeAnalysis.SuppressMessage(
        "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode",
        Justification = "Constructor is called via reflection")]
    private MyPlugin(int arg)
    {
        throw new NotImplementedException();
    }
}

(ฉันไม่รู้ แต่สันนิษฐานว่า CLI รองรับคุณสมบัติที่คล้ายกับ Java ที่ฉันพูดถึงถ้าใครรู้ว่ามันคืออะไรโปรดแก้ไขคำตอบของฉันเพื่ออ้างอิงถึงมัน ... )
Jules

stackoverflow.com/q/10926385/5934037ดูเหมือนว่า
Laiv

1
ฉันได้ค้นพบเมื่อเร็ว ๆ นี้ว่าการทดสอบและการครอบคลุม mesuring (ใน java) เป็นวิธีที่ดีที่จะรู้ว่าบล็อกของโค้ดนั้นไม่ได้ใช้จริงหรือไม่ จากนั้นฉันสามารถลบออกหรือดูว่าทำไมจึงไม่ได้ใช้ (ถ้าฉันคาดหวังตรงกันข้าม) ในขณะที่การค้นหาคือเมื่อฉันให้ความสำคัญกับความคิดเห็น
Laiv

มีอยู่SuppressMessageAttribute( msdn.microsoft.com/en-us/library/… ) ข้อความที่ใกล้เคียงที่สุดคือCA1811: Avoid uncalled private code( msdn.microsoft.com/en-us/library/ms182264.aspx ); ฉันยังไม่พบข้อความสำหรับรหัสสาธารณะ
Kasper van den Berg

2

อีกทางเลือกหนึ่งในการทำเอกสารคือการทดสอบหน่วยเพื่อให้แน่ใจว่าการเรียกการสะท้อนกลับทำงานได้สำเร็จ

ด้วยวิธีนี้หากมีคนเปลี่ยนแปลงหรือลบวิธีการสร้าง / ทดสอบของคุณควรแจ้งเตือนคุณว่าคุณมีบางสิ่งบางอย่างผิดปกติ


0

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


โดยปกติมรดกที่แท้จริงจะเป็นไป และชั้นเรียนมีความเกี่ยวข้องกันโดยมรดก แต่การสร้างอินสแตนซ์ใหม่นอกเหนือจากการสืบทอด นอกจากนี้ฉันยังต้องพึ่งพา 'การสืบทอด' ของเมธอดแบบสแตติกและเนื่องจาก C # ไม่รองรับสล็อตคลาส มีวิธีรอบที่ฉันใช้ แต่ที่อยู่นอกเหนือขอบเขตของความคิดเห็นนี้
Kasper van den Berg
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.