Resharper ชอบที่จะชี้ให้เห็นถึงฟังก์ชั่นหลาย ๆ ต่อหน้า asp.net ที่สามารถทำให้คงที่ มันช่วยฉันได้ไหมถ้าฉันทำให้มันคงที่? ฉันควรทำให้พวกเขาคงที่และย้ายไปยังคลาสยูทิลิตี้?
Resharper ชอบที่จะชี้ให้เห็นถึงฟังก์ชั่นหลาย ๆ ต่อหน้า asp.net ที่สามารถทำให้คงที่ มันช่วยฉันได้ไหมถ้าฉันทำให้มันคงที่? ฉันควรทำให้พวกเขาคงที่และย้ายไปยังคลาสยูทิลิตี้?
คำตอบ:
วิธีสแตติกกับวิธีอินสแตนซ์
10.2.5 สมาชิกแบบสแตติกและอินสแตนซ์ของข้อกำหนดภาษา C # อธิบายถึงความแตกต่าง โดยทั่วไปวิธีการแบบคงที่สามารถให้การปรับปรุงประสิทธิภาพขนาดเล็กมากผ่านวิธีการอินสแตนซ์ แต่ในสถานการณ์ที่ค่อนข้างรุนแรงเท่านั้น (ดูคำตอบนี้สำหรับรายละเอียดเพิ่มเติมเกี่ยวกับเรื่องนั้น)
กฎ CA1822 ใน FxCop หรือสถานะการวิเคราะห์รหัส:
"หลังจาก [ทำเครื่องหมายสมาชิกเป็นแบบคงที่] คอมไพเลอร์จะส่งไซต์การโทรที่ไม่ใช่เสมือนไปยังสมาชิกเหล่านี้ซึ่งจะป้องกันการตรวจสอบที่รันไทม์สำหรับการโทรแต่ละครั้งที่ทำให้มั่นใจว่าตัวชี้วัตถุปัจจุบันไม่เป็นโมฆะ สำหรับรหัสที่ไวต่อประสิทธิภาพในบางกรณีความล้มเหลวในการเข้าถึงอินสแตนซ์วัตถุปัจจุบันแสดงถึงปัญหาความถูกต้อง "
คลาสยูทิลิตี้
คุณไม่ควรย้ายไปยังคลาสยูทิลิตี้เว้นแต่จะเหมาะสมในการออกแบบของคุณ หากวิธีการคงที่เกี่ยวข้องกับประเภทเฉพาะเช่นToRadians(double degrees)
วิธีการที่เกี่ยวข้องกับชั้นเรียนที่เป็นตัวแทนมุมมันทำให้รู้สึกว่าวิธีการที่จะมีอยู่ในฐานะสมาชิกคงที่ของประเภทนั้น (หมายเหตุนี้เป็นตัวอย่างที่ซับซ้อนสำหรับวัตถุประสงค์ของการสาธิต)
ประสิทธิภาพการทำงานเนมสเปซและอื่น ๆ ล้วนเป็นเรื่องรองในมุมมองของฉัน ถามตัวเองว่าอะไรคือเหตุผล วิธีการดำเนินการทางตรรกะในอินสแตนซ์ของประเภทหรือมันเกี่ยวข้องกับประเภทเอง? หากเป็นวิธีหลังให้ใช้วิธีคงที่ ย้ายไปไว้ในคลาสยูทิลิตี้เฉพาะเมื่อมันเกี่ยวข้องกับประเภทที่ไม่ได้อยู่ในการควบคุมของคุณ
บางครั้งมีวิธีการที่มีเหตุผลทำหน้าที่เกี่ยวกับอินสแตนซ์ แต่ไม่ได้เกิดขึ้นกับการใช้งานใด ๆ ของรัฐเช่นนั้นเลย ตัวอย่างเช่นหากคุณกำลังสร้างระบบไฟล์และคุณมีแนวคิดของไดเรกทอรี แต่คุณยังไม่ได้ใช้มันคุณสามารถเขียนคุณสมบัติที่ส่งคืนชนิดของวัตถุระบบไฟล์และมันจะเป็นเพียงแค่ "ไฟล์" - แต่มันเกี่ยวกับเหตุผลอย่างมีเหตุผลและควรเป็นวิธีการเช่น สิ่งนี้ก็มีความสำคัญหากคุณต้องการทำให้เมธอดเสมือน - การใช้งานเฉพาะของคุณอาจไม่จำเป็นต้องระบุสภาวะ แต่คลาสที่ได้รับอาจ (ตัวอย่างเช่นถามคอลเลกชันว่าเป็นแบบอ่านอย่างเดียวหรือไม่ - คุณอาจยังไม่ได้ใช้รูปแบบอ่านอย่างเดียวของคอลเลกชันนั้น แต่เป็นคุณสมบัติของคอลเลกชันเองอย่างชัดเจนไม่ใช่ประเภท)
การทำเครื่องหมายเมธอดstatic
ในคลาสทำให้เห็นได้ชัดว่าไม่ได้ใช้สมาชิกอินสแตนซ์ใด ๆ ซึ่งจะเป็นประโยชน์ในการรู้เมื่ออ่านผ่านโค้ด
คุณไม่จำเป็นต้องย้ายไปที่คลาสอื่นเว้นแต่ว่าจะมีการแชร์คลาสอื่นที่เชื่อมโยงกันอย่างใกล้ชิดและเป็นแนวคิดที่ชาญฉลาด
ฉันแน่ใจว่านี่ไม่ได้เกิดขึ้นในกรณีของคุณ แต่มี "กลิ่นเหม็น" ที่ฉันเคยเห็นในรหัสบางอย่างฉันต้องทนทุกข์ทรมานจากการบำรุงรักษาที่ใช้วิธีการคงที่จำนวนมาก
น่าเสียดายที่มันเป็นวิธีการคงที่ที่ถือว่าเป็นสถานะแอปพลิเคชันโดยเฉพาะ (ทำไมต้องแน่ใจว่าเราจะมีผู้ใช้เพียงคนเดียวต่อแอปพลิเคชัน! ทำไมไม่มีคลาสผู้ใช้ติดตามสิ่งนั้นในตัวแปรสแตติก?) พวกเขาได้รับการยกย่องในการเข้าถึงตัวแปรทั่วโลก พวกเขายังมีตัวสร้างแบบคงที่ (!) ซึ่งเกือบจะเป็นความคิดที่ดีเสมอ (ฉันรู้ว่ามีข้อยกเว้นที่สมเหตุสมผลสองสามข้อ)
อย่างไรก็ตามวิธีการแบบสแตติกมีประโยชน์มากเมื่อแยกออกจากตรรกะโดเมนที่ไม่ได้ขึ้นอยู่กับสถานะของอินสแตนซ์ของวัตถุ พวกเขาสามารถทำให้โค้ดของคุณอ่านได้มากขึ้น
เพียงให้แน่ใจว่าคุณกำลังวางพวกเขาในสถานที่ที่เหมาะสม เป็นวิธีการคงที่อย่างคร่าวๆจัดการสถานะภายในของวัตถุอื่น ๆ ? กรณีที่ดีสามารถทำให้พฤติกรรมของพวกเขาเป็นหนึ่งในชั้นเรียนเหล่านั้นแทนได้หรือไม่? หากคุณแยกข้อกังวลออกไม่ถูกต้องคุณอาจปวดหัวในภายหลัง
นี่คือการอ่านที่น่าสนใจ:
http://thecuttingledge.com/?p=57
ReSharper ไม่ได้แนะนำให้คุณทำให้วิธีการของคุณคงที่ คุณควรถามตัวเองว่าทำไมวิธีการนั้นถึงอยู่ในคลาสนั้นแทนที่จะพูดว่าหนึ่งในคลาสที่แสดงในลายเซ็นของมัน ...
แต่นี่คือสิ่งที่ resharper documentaion พูดว่า: http://confluence.jetbrains.net/display/ReSharper/Member+can+be+made+static
เพียงเพิ่มคำตอบของ @Jason True สิ่งสำคัญคือต้องตระหนักว่าการใส่ 'คงที่' บนวิธีการไม่รับประกันว่าวิธีการนั้นจะ 'บริสุทธิ์' มันจะไร้สัญชาติโดยคำนึงถึงคลาสที่มีการประกาศ แต่อาจเข้าถึงวัตถุ 'สถิต' อื่น ๆ ที่มีสถานะ (การกำหนดค่าแอปพลิเคชัน ฯลฯ ) สิ่งนี้อาจไม่ได้เป็นสิ่งเลวร้ายเสมอไป แต่เป็นหนึ่งในเหตุผลที่ โดยส่วนตัวแล้วฉันมักจะชอบวิธีการแบบคงที่เมื่อฉันสามารถเป็นได้ว่าถ้าพวกเขาบริสุทธิ์คุณสามารถทดสอบและเหตุผลเกี่ยวกับพวกเขาในการแยกโดยไม่ต้องกังวลเกี่ยวกับสถานะโดยรอบ
คุณควรทำสิ่งที่สามารถอ่านได้และใช้งานง่ายที่สุดในสถานการณ์ที่กำหนด
อาร์กิวเมนต์ประสิทธิภาพไม่ดียกเว้นในสถานการณ์ที่รุนแรงที่สุดเนื่องจากมีเพียงสิ่งเดียวที่เกิดขึ้นจริงคือพารามิเตอร์พิเศษหนึ่งตัว ( this
) กำลังถูกผลักลงบนสแต็กสำหรับวิธีการเช่น
สำหรับตรรกะที่ซับซ้อนภายในชั้นเรียนฉันได้พบวิธีการคงที่ส่วนตัวที่มีประโยชน์ในการสร้างตรรกะที่แยกซึ่งอินพุตอินสแตนซ์จะถูกกำหนดไว้อย่างชัดเจนในลายเซ็นวิธีการและไม่มีผลข้างเคียงของอินสแตนซ์ เอาท์พุททั้งหมดจะต้องผ่านค่าตอบแทนหรือพารามิเตอร์ออก / อ้างอิง การแบ่งตรรกะที่ซับซ้อนออกเป็นบล็อกโค้ดที่ไม่มีผลข้างเคียงสามารถปรับปรุงความสามารถในการอ่านของโค้ดและความมั่นใจของทีมพัฒนา
ในทางตรงกันข้ามมันสามารถนำไปสู่ชั้นเรียนที่ปนเปื้อนโดยการแพร่กระจายของวิธีการยูทิลิตี้ ตามปกติการตั้งชื่อแบบลอจิคัลเอกสารและแอปพลิเคชันที่สอดคล้องกันของอนุสัญญาการเข้ารหัสทีมสามารถบรรเทาปัญหานี้ได้
ReSharper ไม่ได้ตรวจสอบตรรกะ มันจะตรวจสอบว่าวิธีการใช้สมาชิกอินสแตนซ์ หากวิธีนั้นเป็นแบบส่วนตัวและเรียกใช้โดยวิธีการอินสแตนซ์ (อาจเป็นเพียงหนึ่งเดียว) นี่เป็นสัญญาณเพื่อให้มันเป็นวิธีการแบบอินสแตนซ์
หากฟังก์ชั่นนั้นใช้ร่วมกันในหลาย ๆ หน้าคุณสามารถใส่มันลงในคลาสของเพจฐานแล้วให้เพจ asp.net ทั้งหมดที่ใช้ฟังก์ชันนั้นสืบทอดมาจากฟังก์ชันนั้น
ทำให้วิธีการคงที่หมายความว่าคุณสามารถเรียกวิธีการจากนอกชั้นเรียนโดยไม่ต้องสร้างอินสแตนซ์ของชั้นเรียนที่แรก สิ่งนี้มีประโยชน์เมื่อทำงานกับออบเจ็กต์หรือส่วนเสริมของผู้ผลิตรายอื่น ลองนึกภาพถ้าคุณต้องสร้างวัตถุคอนโซล "con" ก่อนโทร con.Writeline ();
ช่วยควบคุมเนมสเปซมลพิษ
Class.a_core_function( .. )
vsa_core_function( .. )
เพียงแค่ความน่าเชื่อถือของฉัน: การเพิ่มวิธีการคงที่ที่ใช้ร่วมกันทั้งหมดไปยังคลาสยูทิลิตี้ช่วยให้คุณสามารถเพิ่ม
using static className;
ในการใช้ข้อความสั่งของคุณซึ่งทำให้โค้ดพิมพ์ได้เร็วขึ้นและอ่านง่ายขึ้น ตัวอย่างเช่นฉันมีจำนวนมากของสิ่งที่จะเรียกว่า "ตัวแปรทั่วโลก" ในรหัสที่ฉันสืบทอด แทนที่จะสร้างตัวแปรทั่วโลกในคลาสที่เป็นคลาสอินสแตนซ์ฉันตั้งค่าให้พวกเขาทั้งหมดเป็นคุณสมบัติคงที่ของคลาสระดับโลก มันทำงานได้ถ้ายุ่งและฉันก็สามารถอ้างอิงคุณสมบัติตามชื่อเพราะฉันมี namespace คงที่อ้างอิงแล้ว
ฉันไม่รู้ว่านี่เป็นการฝึกฝนที่ดีหรือไม่ ฉันมีอะไรมากมายที่ต้องเรียนรู้เกี่ยวกับ C # 4/5 และรหัสดั้งเดิมที่มากพอที่จะทำให้มั่นใจได้ว่าฉันเพิ่งจะปล่อยให้เคล็ดลับ Roselyn แนะนำฉัน
โจอี้
ฉันหวังว่าคุณได้เข้าใจความแตกต่างระหว่างวิธีการคงที่และอินสแตนซ์แล้ว นอกจากนี้อาจมีคำตอบยาวและคำตอบสั้น ๆ ผู้อื่นให้คำตอบนานแล้ว
คำตอบสั้น ๆ ของฉัน: ใช่คุณสามารถแปลงเป็นวิธีคงที่หาก Resharper แนะนำ ไม่มีอันตรายใด ๆ ในการทำเช่นนั้น แต่ด้วยการทำให้เมธอดคงที่คุณกำลังปกป้องเมธอดอยู่ดังนั้นคุณไม่ต้องส่งสมาชิกอินสแตนซ์ใด ๆ ไปยังเมธอดนั้นโดยไม่จำเป็น ด้วยวิธีนี้คุณสามารถบรรลุหลักการ OOP " ลดการเข้าถึงชั้นเรียนและสมาชิกให้น้อยที่สุด"
เมื่อ ReSharper แนะนำว่าวิธีการอินสแตนซ์สามารถแปลงเป็นวิธีการแบบคงที่ได้จริง ๆ แล้วจะบอกคุณว่า "ทำไม .. วิธีนี้กำลังนั่งอยู่ในชั้นเรียนนี้เพราะมันไม่ได้ใช้งานจริง ๆ ดังนั้นมันจึงให้อาหารแก่คุณ จากนั้นก็เป็นคุณที่สามารถตระหนักถึงความจำเป็นในการย้ายวิธีการนั้นไปยังคลาสยูทิลิตี้คงที่หรือไม่ ตามหลักการของ SOLID ชั้นเรียนควรมีความรับผิดชอบหลักเพียงข้อเดียว ดังนั้นคุณสามารถทำความสะอาดชั้นเรียนของคุณได้ดีขึ้น บางครั้งคุณต้องการวิธีการช่วยเหลือบางอย่างแม้ในคลาสอินสแตนซ์ของคุณ หากเป็นเช่นนั้นคุณอาจเก็บไว้ในตัวช่วย #region