ฉันจะใช้ผู้รับมอบสิทธิ์ได้ที่ไหน [ปิด]


109

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

คำตอบ:


33

ผู้รับมอบสิทธิ์คือชื่อประเภทที่กำหนดวิธีการเฉพาะ เช่นเดียวกับคำจำกัดความของคลาสที่จัดวางสมาชิกทั้งหมดสำหรับชนิดของอ็อบเจ็กต์ที่กำหนดผู้ร่วมประชุมจะวางลายเซ็นเมธอดสำหรับชนิดของวิธีการที่กำหนด

จากคำสั่งนี้ผู้ร่วมประชุมเป็นตัวชี้ฟังก์ชันและกำหนดลักษณะของฟังก์ชันนั้น

ตัวอย่างที่ดีสำหรับการใช้งานจริงในโลกของผู้แทนเป็นคำกริยา ในตัวอย่างจากลิงค์คุณจะสังเกตเห็นว่าArray.Findใช้อาร์เรย์เพื่อค้นหาจากนั้นเพรดิเคตเพื่อจัดการกับเกณฑ์ของสิ่งที่จะค้นหา ในกรณีนี้จะส่งผ่านเมธอด ProductGT10 ซึ่งตรงกับลายเซ็นเพรดิเคต


154

ตามที่ระบุไว้ใน"Learning C # 3.0: Master the fundamentals of C # 3.0"

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

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

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

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


1
ทำไมไม่ใช้ฟังก์ชันนิรนาม / lambdas ล่ะ?
Pacerier

5
@Pacerier นี่เป็นการตอบช้าและคุณอาจค้นพบคำตอบแล้ว แต่เพื่อประโยชน์ของผู้อ่านคนอื่น ๆ ที่พบสิ่งนี้ฟังก์ชันที่ไม่ระบุตัวตนคือผู้รับมอบสิทธิ์ประเภทหนึ่ง
Anthony

10
@ Anthony + Pacerier: วิธีการที่ไม่เหมาะสมไม่ใช่การมอบหมาย วิธีการไม่ระบุตัวตนเป็นส่วนหนึ่งของรหัส ผู้รับมอบสิทธิ์คือตัวชี้ที่ชี้ไปที่ส่วนของรหัสนั้น คุณไม่สามารถมีวิธีการที่ผิดปกติได้หากไม่มีผู้รับมอบสิทธิ์ชี้ไปที่มันมิฉะนั้นจะไม่มีการเรียกใช้ แลมด้าเป็นตัวดำเนินการที่ใช้สร้างนิพจน์แลมด้า นิพจน์แลมบ์ดาส่วนใหญ่ส่งผลให้เกิดวิธีการที่ไม่เหมาะสมซึ่งจะถูกชี้โดย ... ผู้แทน
Martin Mulder

โง่ฉัน แต่ฉันจะสร้างคำสั่ง If ElseIf ถ้าฉันไม่รู้จักการใช้งานเมื่อกดปุ่ม ฉันบอกว่าฉันโง่
JustJohn

@Pacerier วิธีการไม่ระบุชื่อที่นำมาใช้ใน C # 2.0 และ Lambda ที่นำมาใช้ใน C # 3.0 หาก Lambda เปิดตัวก่อนจะไม่เคยมีวิธีการที่ไม่ระบุตัวตนและแม้แต่มอบหมาย!
AminM

18

การใช้งานทั่วไปอย่างหนึ่งของผู้รับมอบสิทธิ์สำหรับรายการทั่วไปคือผ่านทางผู้รับมอบสิทธิ์การดำเนินการ (หรือสิ่งที่เทียบเท่าที่ไม่ระบุชื่อ) เพื่อสร้างการดำเนินการ foreach หนึ่งบรรทัด:

myList.Foreach( i => i.DoSomething());

ฉันยังพบว่าผู้รับมอบสิทธิ์พรีดิเคตมีประโยชน์มากในการค้นหาหรือตัดทอนรายการ:

myList.FindAll( i => i.Name == "Bob");    
myList.RemoveAll( i => i.Name == "Bob");

ฉันรู้ว่าคุณบอกว่าไม่ต้องใช้รหัส แต่ฉันพบว่ามันง่ายกว่าที่จะแสดงประโยชน์ผ่านรหัส :)


13

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


5

หากคุณสนใจที่จะดูว่ารูปแบบ Delegate ใช้ในโค้ดในโลกแห่งความเป็นจริงอย่างไรไม่ต้องมองหาที่ไหนไกลนอกจาก Cocoa บน Mac OS X Cocoa เป็นชุดเครื่องมือ UI ที่เป็นที่ต้องการของ Apple สำหรับการเขียนโปรแกรมภายใต้ Mac OS X และมีการเข้ารหัสใน Objective C ออกแบบมาเพื่อให้องค์ประกอบ UI แต่ละส่วนถูกขยายผ่านการมอบหมายมากกว่าการคลาสย่อยหรือวิธีการอื่น ๆ

สำหรับข้อมูลเพิ่มเติมผมขอแนะนำให้ตรวจสอบสิ่งที่แอปเปิ้ลได้กล่าวเกี่ยวกับผู้ได้รับมอบหมายที่นี่


5

ฉันมีโครงการที่ใช้ win32 Python

เนื่องจากสาเหตุหลายประการบางโมดูลจึงใช้ odbc.py เพื่อเข้าถึง DB และโมดูลอื่น ๆ - pyodbc.py

เกิดปัญหาเมื่อจำเป็นต้องใช้ฟังก์ชันกับโมดูลทั้งสองประเภท มันมีออบเจ็กต์การเชื่อมต่อที่ส่งผ่านไปยังอาร์กิวเมนต์ แต่ก็ต้องรู้ว่าจะใช้ dbi.dbiDate หรือวันที่เวลาเพื่อแสดงเวลา

เนื่องจากคาดว่า odbc.py เป็นค่าในคำสั่ง SQL วันที่เป็น dbi.dbiDate ในขณะที่ pyodbc.py คาดหวังค่าวันที่และเวลา

ความซับซ้อนอีกอย่างหนึ่งคืออ็อบเจ็กต์การเชื่อมต่อที่สร้างโดย odbc.py และ pyodbc.py ไม่อนุญาตให้ตั้งค่าฟิลด์เพิ่มเติม

วิธีแก้ปัญหาของฉันคือการรวมอ็อบเจกต์การเชื่อมต่อที่ส่งคืนโดย odbc.odbc (... ) และ pyodbc.pyodbc (... ) โดยคลาส delegate ซึ่งมีฟังก์ชันการแทนเวลาที่ต้องการเป็นค่าของฟิลด์พิเศษและผู้รับมอบสิทธิ์ใด การร้องขอฟิลด์อื่น ๆ ทั้งหมดไปยังออบเจ็กต์การเชื่อมต่อดั้งเดิม


5

ฉันมีคำถามเดียวกับคุณและไปที่ไซต์นี้เพื่อหาคำตอบ

เห็นได้ชัดว่าฉันไม่เข้าใจมันดีขึ้นแม้ว่าฉันจะอ่านตัวอย่างในหัวข้อนี้

ตอนนี้ฉันพบการใช้งานที่ยอดเยี่ยมสำหรับผู้ร่วมประชุมที่ฉันอ่าน: http://www.c-sharpcorner.com/UploadFile/thiagu304/passdata05172006234318PM/passdata.aspx

สิ่งนี้อาจดูเหมือนชัดเจนสำหรับผู้ใช้ใหม่เนื่องจากแบบฟอร์มมีความซับซ้อนในการส่งผ่านค่ามากกว่าเว็บไซต์ ASP.NET ที่มี POST / GET (QueryString) ..

โดยทั่วไปคุณกำหนดผู้รับมอบสิทธิ์ซึ่งรับ"TextBox text "เป็นพารามิเตอร์

// Form1

// Class Property Definition
public delegate void delPassData(TextBox text);


// Click Handler
private void btnSend_Click(object sender, System.EventArgs e)
{
     Form2 frm= new Form2();
     delPassData del=new delPassData(frm.funData);
     del(this.textBox1);
     frm.Show();
}

// สรุป: กำหนดการมอบหมายสร้างอินสแตนซ์คลาส Form2 ใหม่กำหนดฟังก์ชัน funData () เพื่อมอบสิทธิ์ส่งผ่าน textBox ของคุณไปยังผู้รับมอบสิทธิ์ แสดงแบบฟอร์ม

// แบบ 2

public void passData(TextBox txtForm1)
{

     label1.Text = txtForm1.Text;
}

// สรุป: เพียงแค่ใช้ TextBox txtForm1 เป็นพารามิเตอร์ (ตามที่กำหนดไว้ในผู้รับมอบสิทธิ์ของคุณ) และกำหนดข้อความป้ายกำกับให้กับข้อความของ textBox

ฉันหวังว่าสิ่งนี้จะช่วยให้ความกระจ่างในการใช้งานกับผู้ได้รับมอบหมาย :) ..


ไม่ว่าเมธอดคลาส Form2 จะต้องตั้งชื่อ funData (แทน passData) หรือการกำหนดฟังก์ชัน Form1 จะต้องมีชื่อว่า frm.passData (แทนที่จะเป็น frm.funData)
ethan

1

ค้นหา Google อย่างรวดเร็วมาด้วยนี้http://en.wikipedia.org/wiki/Delegation_pattern โดยทั่วไปเมื่อใดก็ตามที่คุณใช้วัตถุที่ส่งต่อการเรียกร้องไปยังวัตถุอื่นจากนั้นคุณจะมอบหมาย

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