C # รู้คำสองคำ, และdelegate
event
เริ่มจากอันแรกกันเถอะ
ตัวแทน
A delegate
เป็นการอ้างอิงถึงวิธีการ เช่นเดียวกับที่คุณสามารถสร้างการอ้างอิงไปยังอินสแตนซ์:
MyClass instance = myFactory.GetInstance();
คุณสามารถใช้ผู้รับมอบสิทธิ์เพื่อสร้างการอ้างอิงถึงวิธีการ:
Action myMethod = myFactory.GetInstance;
ตอนนี้คุณมีการอ้างอิงถึงเมธอดคุณสามารถเรียกใช้เมธอดผ่านการอ้างอิง:
MyClass instance = myMethod();
แต่ทำไมล่ะ คุณสามารถโทรmyFactory.GetInstance()
โดยตรงได้ ในกรณีนี้คุณสามารถ อย่างไรก็ตามมีหลายกรณีที่ต้องพิจารณาว่าคุณไม่ต้องการให้แอปพลิเคชั่นที่เหลือมีความรู้myFactory
หรือโทรmyFactory.GetInstance()
โดยตรง
เห็นได้ชัดอย่างใดอย่างหนึ่งคือถ้าคุณต้องการที่จะสามารถที่จะเปลี่ยนmyFactory.GetInstance()
ลงไปmyOfflineFakeFactory.GetInstance()
จากสถานที่หนึ่งกลาง (aka รูปแบบการโรงงาน )
รูปแบบวิธีการของโรงงาน
ดังนั้นถ้าคุณมีTheOtherClass
คลาสและจำเป็นต้องใช้myFactory.GetInstance()
นี่คือลักษณะของโค้ดโดยไม่มีผู้รับมอบสิทธิ์ (คุณจะต้องแจ้งให้TheOtherClass
ทราบเกี่ยวกับประเภทของคุณmyFactory
):
TheOtherClass toc;
//...
toc.SetFactory(myFactory);
class TheOtherClass
{
public void SetFactory(MyFactory factory)
{
// set here
}
}
หากคุณต้องการใช้ผู้ร่วมประชุมคุณไม่ต้องเปิดเผยประเภทโรงงานของฉัน:
TheOtherClass toc;
//...
Action factoryMethod = myFactory.GetInstance;
toc.SetFactoryMethod(factoryMethod);
class TheOtherClass
{
public void SetFactoryMethod(Action factoryMethod)
{
// set here
}
}
ดังนั้นคุณสามารถมอบสิทธิ์ให้ผู้อื่นในคลาสอื่นได้โดยไม่ต้องเปิดเผยประเภทของพวกเขา สิ่งเดียวที่คุณเปิดเผยก็คือลายเซ็นต์ของวิธีการของคุณ (จำนวนพารามิเตอร์ที่คุณมีและเช่นนั้น)
"ลายเซ็นวิธีการของฉัน" ฉันเคยได้ยินเรื่องนี้มาก่อนที่ไหน ใช่แล้ว อินเตอร์เฟสอธิบายลายเซ็นของคลาสทั้งหมด ลองนึกถึงผู้ร่วมประชุมว่าเป็นลายเซ็นของวิธีการเดียวเท่านั้น!
ข้อแตกต่างระหว่างอินเทอร์เฟซและผู้รับมอบสิทธิ์ที่มีขนาดใหญ่อีกข้อหนึ่งคือเมื่อคุณเขียนชั้นเรียนคุณไม่ต้องพูดกับ C # "วิธีนี้ใช้ตัวแทนประเภทนั้น" ด้วยอินเทอร์เฟซคุณจำเป็นต้องพูดว่า "คลาสนี้ใช้อินเทอร์เฟซชนิดนั้น"
นอกจากนี้การอ้างอิงผู้รับมอบสิทธิ์สามารถ (มีข้อ จำกัด บางอย่างดูด้านล่าง) อ้างอิงหลายวิธี (เรียกว่าMulticastDelegate
) ซึ่งหมายความว่าเมื่อคุณโทรหาผู้ร่วมประชุมจะมีการดำเนินการวิธีการหลายวิธีที่แนบมาอย่างชัดเจน การอ้างอิงวัตถุสามารถอ้างอิงได้เพียงหนึ่งวัตถุเท่านั้น
ข้อ จำกัด สำหรับ a MulticastDelegate
คือลายเซ็น (method / ผู้รับมอบสิทธิ์) ไม่ควรมีค่าส่งคืน ( void
) และคำหลักout
และref
ไม่ได้ใช้ในลายเซ็น เห็นได้ชัดว่าคุณไม่สามารถเรียกสองวิธีที่ส่งคืนหมายเลขและคาดหวังให้ส่งคืนหมายเลขเดิม MulticastDelegate
เมื่อลายเซ็นสอดคล้องที่ผู้ร่วมประชุมเป็นโดยอัตโนมัติ
เหตุการณ์
เหตุการณ์เป็นเพียงคุณสมบัติ (เช่น get; set; properties to field instance) ซึ่งแสดงการสมัครสมาชิกไปยังผู้รับมอบสิทธิ์จากวัตถุอื่น ๆ อย่างไรก็ตามคุณสมบัติเหล่านี้ไม่รองรับรับ; set; พวกเขาสนับสนุนการเพิ่ม; ลบ;
ดังนั้นคุณสามารถมี:
Action myField;
public event Action MyProperty
{
add { myField += value; }
remove { myField -= value; }
}
การใช้งานใน UI (WinForms, WPF, UWP เป็นต้น)
ดังนั้นตอนนี้เรารู้ว่าผู้ได้รับมอบหมายเป็นการอ้างอิงถึงวิธีการและเราสามารถมีเหตุการณ์ที่จะทำให้โลกรู้ว่าพวกเขาสามารถให้วิธีการที่จะอ้างอิงจากผู้ได้รับมอบหมายของเราและเราเป็นปุ่ม UI จากนั้น: เรา สามารถถามใครก็ได้ที่สนใจว่าฉันคลิกเพื่อลงทะเบียนวิธีการของพวกเขากับเรา (ผ่านเหตุการณ์ที่เราสัมผัส) เราสามารถใช้วิธีการทั้งหมดที่ได้รับจากเราและอ้างอิงโดยตัวแทนของเรา จากนั้นเราจะรอและรอจนกว่าผู้ใช้จะมาถึงและคลิกที่ปุ่มจากนั้นเราจะมีเหตุผลเพียงพอที่จะเรียกผู้แทน และเนื่องจากผู้ได้รับมอบหมายอ้างอิงวิธีการทั้งหมดที่ให้ไว้กับเราวิธีการเหล่านั้นทั้งหมดจะถูกเรียกใช้ เราไม่รู้ว่าวิธีการเหล่านั้นทำอะไรและเราไม่รู้ว่าชั้นเรียนใดใช้วิธีการเหล่านั้น สิ่งที่เราใส่ใจคือคนที่สนใจเราถูกคลิก
ชวา
ภาษาอย่าง Java ไม่มีผู้รับมอบสิทธิ์ พวกเขาใช้อินเทอร์เฟซแทน วิธีที่พวกเขาทำคือขอให้ทุกคนที่สนใจใน 'เราถูกคลิก' เพื่อใช้อินเทอร์เฟซบางอย่าง (ด้วยวิธีการบางอย่างที่เราสามารถเรียกได้) จากนั้นให้อินสแตนซ์ทั้งหมดที่ใช้อินเทอร์เฟซ เราเก็บรายการของวัตถุทั้งหมดที่ใช้อินเทอร์เฟซนี้และสามารถเรียก 'วิธีการบางอย่างที่เราสามารถเรียกได้' ทุกครั้งที่เราคลิก