การใช้คำสำคัญ“ นี้” ในพารามิเตอร์ที่เป็นทางการสำหรับวิธีการคงที่ใน C #


286

ฉันพบรหัส C # หลายครั้งเช่น:

public static int Foo(this MyClass arg)

ฉันไม่สามารถค้นหาคำอธิบายความthisหมายของคำหลักได้ในกรณีนี้ ข้อมูลเชิงลึกใด ๆ


10
นอกจากนี้ยังมีคำตอบที่ได้รับการยอมรับสำหรับ C # วิธีการขยายหนึ่งจะต้องตรวจสอบอย่างเป็นทางการMSDN เอกสาร
Raven vulcan

4
วิธีการขยายมีความสะดวก แต่เราต้องใช้ความระมัดระวังเมื่อสร้าง / ใช้พวกเขา - พวกเขาสามารถทำลาย! อ้างจากหลักเกณฑ์ทั่วไปในเอกสารอย่างเป็นทางการของ MSDN : "โดยทั่วไปเราขอแนะนำให้คุณใช้วิธีการขยายอย่าง จำกัด และเฉพาะเมื่อคุณต้อง ... เมื่อใช้วิธีการขยายเพื่อขยายประเภทที่มีซอร์สโค้ดคุณไม่สามารถเปลี่ยนแปลงได้ รับความเสี่ยงที่การเปลี่ยนแปลงในการใช้งานประเภทนั้นจะทำให้วิธีการขยายของคุณแตกหัก "
กฤษณะ Gupta

นั่นหมายความว่าสิ่งนี้จะเป็นไปได้หรือไม่? เพราะนั่นคือสิ่งที่ฉันกำลังมองหา
facepalm42

คำตอบ:


274

นี้เป็นวิธีขยาย ดูคำอธิบายที่นี่

วิธีการขยายช่วยให้นักพัฒนาสามารถเพิ่มวิธีการใหม่ในสัญญาสาธารณะของประเภท CLR ที่มีอยู่โดยไม่ต้อง sub-class หรือคอมไพล์ชนิดเดิม วิธีการขยายช่วยผสมผสานความยืดหยุ่นของการสนับสนุน "การพิมพ์เป็ด" ที่เป็นที่นิยมในภาษาแบบไดนามิกในปัจจุบันด้วยการตรวจสอบประสิทธิภาพและการรวบรวมเวลาของภาษาที่พิมพ์อย่างยิ่ง

วิธีการขยายเปิดใช้งานสถานการณ์ที่มีประโยชน์หลากหลายและช่วยทำให้กรอบการสืบค้น LINQ ที่ทรงพลังจริงๆ ...

หมายความว่าคุณสามารถโทรได้

MyClass myClass = new MyClass();
int i = myClass.Foo();

ค่อนข้างมากกว่า

MyClass myClass = new MyClass();
int i = Foo(myClass);

สิ่งนี้ทำให้สามารถสร้างส่วนต่อประสานที่คล่องแคล่วดังที่ระบุไว้ด้านล่าง


การจัด
Gerry

@Gerry - คุณหมายถึงอะไร
Preet Sangha

9
ขออภัยเหน็บแนมเล็กน้อย - ไวยากรณ์จำนวนมากวันนี้ดูเหมือนจะแก้ปัญหาที่ฉันไม่ได้รู้ว่ามีปัญหา การอ่านควรมีความสำคัญสูงมาก
Gerry

2
จะเป็น @Gerry เที่ยงตรง, ชนิดของมันเสียงเหมือนคุณอยู่ในคลาสสิกร้องไห้สะอึกสะอื้น Paradox ไวยากรณ์จำนวนมากในทุกวันนี้แก้ปัญหาที่คุณไม่ได้เพราะคุณไม่รู้ว่ามีวิธีที่ดีกว่าหรือคุณไม่ได้ทำงานที่ไวยากรณ์นี้ยอดเยี่ยม ความคิดเห็นส่วนใหญ่เกี่ยวกับ ' นี่เป็นวิธีแก้ปัญหาในการค้นหาปัญหา ' เป็นตัวอย่างของ ' ฉันไม่รู้ว่าคุณลักษณะดังกล่าวทำงานอย่างไรจึงต้องไร้ประโยชน์ '
Myrddin Emrys

53

โพสต์บล็อกของ Scott Guอธิบายไว้เป็นอย่างดี

สำหรับฉันคำตอบของคำถามอยู่ในข้อความต่อไปนี้ในโพสต์นั้น:

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


9
นี่ควรเป็นคำตอบที่ยอมรับได้ เป็นคำตอบเดียวที่อธิบายถึงวัตถุประสงค์ที่แท้จริงของthisคำสำคัญในลายเซ็นวิธี คำตอบอื่น ๆ เพียงพูดอย่างไม่ช่วยเหลือเพียงบอกว่า "เป็นวิธีส่วนขยาย" ฉันไม่เคยเข้าใจอย่างเต็มที่ว่าวิธีการส่วนขยาย "แนบ" กับประเภทที่ขยายจนกว่าจะอ่านคำตอบนี้ได้อย่างไร ขอบคุณ!
Lews Therin

13

นอกจากคำอธิบายของ Preet Sangha:
Intellisense ยังแสดงวิธีการขยายด้วยลูกศรสีน้ำเงิน (เช่นหน้า "รวม <>"):

ป้อนคำอธิบายรูปภาพที่นี่

คุณต้องการ

using the.namespace.of.the.static.class.with.the.extension.methods;

เพื่อให้วิธีการส่วนขยายปรากฏและพร้อมใช้งานหากอยู่ในเนมสเปซที่แตกต่างจากรหัสที่ใช้


8

พวกเขามีวิธีการขยาย ยินดีต้อนรับสู่ใหม่ทั้งหมดโลกได้อย่างคล่องแคล่ว :)


4

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


1

"this" ขยายคลาสถัดไปในรายการพารามิเตอร์

ดังนั้นในวิธีการด้านล่างนี้ "นี้" ขยาย "สตริง" บรรทัดถูกส่งผ่านไปยังฟังก์ชันเป็นอาร์กิวเมนต์ปกติไปยังเมธอด ประชาชนคงสตริง [] SplitCsvLine (สายสตริงนี้)

ในตัวอย่างข้างต้นคลาส "this" กำลังขยายคลาส "String" ที่มีอยู่ภายใน

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