ความแตกต่างระหว่างเหตุการณ์และผู้ได้รับมอบหมายและการใช้งานตามลำดับ [ปิด]


107

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

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

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


ใช่การห่อหัวของฉันรอบความแตกต่างนั้นยากจริงๆพวกเขาดูเหมือนกันและดูเหมือนจะทำเหมือนกันในตอนแรก
Robert Gould

1
ดูคำถามนี้ด้วย
Dimitri C.

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

คำตอบ:


49

จากมุมมองทางเทคนิคคำตอบอื่น ๆ ได้กล่าวถึงความแตกต่าง

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

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

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


4
บางทีฉันอาจจะขาดอะไรไป แต่ตัวจัดการเหตุการณ์ไม่ใช่ผู้รับมอบสิทธิ์ประเภทใด
Powerlord

1
คำตอบของฉันตอบคำถามแก้ไข # 1 และ # 2; ความแตกต่างจากมุมมองการใช้งาน สำหรับจุดประสงค์ของการสนทนาครั้งนี้พวกเขาแตกต่างกันแม้ว่าคุณจะพูดถูกต้องจากมุมมองทางเทคนิค ดูคำตอบอื่น ๆ สำหรับความแตกต่างทางเทคนิค
Szymon Rozga

3
"ผู้รับมอบสิทธิ์ทั้งหมดใน. Net เป็นผู้รับมอบสิทธิ์หลายผู้รับ"? แม้กระทั่งผู้รับมอบสิทธิ์ที่ส่งคืนค่า?
Qwertie

5
ใช่. สำหรับประวัติ, ดูที่msdn.microsoft.com/en-us/magazine/cc301816.aspx เช็คเอาต์: msdn.microsoft.com/en-us/library/system.delegate.aspx หากส่งคืนค่าค่าที่ส่งกลับจะเป็นการประเมินของผู้รับมอบสิทธิ์คนสุดท้ายในห่วงโซ่
Szymon Rozga

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

55

คีย์เวิร์ดeventคือตัวปรับขอบเขตสำหรับผู้รับมอบสิทธิ์แบบหลายผู้รับ ความแตกต่างในทางปฏิบัติระหว่างสิ่งนี้และการประกาศ multicast delegate มีดังนี้:

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

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

B = new EventHandler(this.MethodB);
C = new EventHandler(this.MethodC);
A = B + C;

ตัวอย่างที่สองแสดงทั้งการมอบหมายโดยตรงและการมอบหมายแบบผสมผสาน

B = new EventHandler(this.MethodB);
C = new EventHandler(this.MethodC);
A = B;
A += C;

ตัวอย่างที่สาม: ไวยากรณ์ที่คุ้นเคยมากขึ้น คุณอาจคุ้นเคยกับการกำหนด null เพื่อลบตัวจัดการทั้งหมด

B = new EventHandler(this.MethodB);
C = new EventHandler(this.MethodC);
A = null;
A += B;
A += C;

เช่นเดียวกับคุณสมบัติเหตุการณ์มีไวยากรณ์เต็มรูปแบบที่ไม่มีใครเคยใช้ นี้:

class myExample 
{
  internal EventHandler eh;

  public event EventHandler OnSubmit 
  { 
    add 
    {
      eh = Delegate.Combine(eh, value) as EventHandler;
    }
    remove
    {
      eh = Delegate.Remove(eh, value) as EventHandler;
    }
  }

  ...
}

... เหมือนกับสิ่งนี้ทุกประการ:

class myExample 
{
  public event EventHandler OnSubmit;
}

วิธีการเพิ่มและลบมีความชัดเจนมากขึ้นในไวยากรณ์ที่ค่อนข้างนิ่งซึ่ง VB.NET ใช้ (ไม่มีตัวดำเนินการมากเกินไป)


6
+ สำหรับ "การเข้าถึงการร้องขอไปยังผู้รับมอบสิทธิ์แบบหลายผู้รับถูก จำกัด ไว้ที่คลาสการประกาศ" นั่นคือจุดแตกต่างที่สำคัญระหว่างผู้รับมอบสิทธิ์และเหตุการณ์
RichardOD

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

4
สะดวกพอ ๆ กับ Google และ stackoverflow ทั้งหมดนี้และอีกมากมายมีให้ในรายละเอียดที่ชวนให้มึนงงในข้อมูลจำเพาะภาษา C # ซึ่งเผยแพร่สู่สาธารณะโดยไม่มีค่าใช้จ่ายจาก Microsoft ฉันรู้ว่าบนใบหน้าของมันพระเจ้าสร้างคู่มือและ Jon Skeet กลืนมัน แต่มีสำเนาอื่น ๆ :)
Peter Wone

12

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

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


นั่นคือสิ่งที่ฉันเห็นเช่นกัน ฉันต้องการคำอธิบายที่ลึกซึ้งและไพเราะกว่านี้ :)

13
น้ำตาลมากเกินไปทำให้อ้วน แต่ ... = P
Erik Forbes

5

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

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

someObj.SomeCallback = MyCallback;  // okay, replaces any existing callback
someObj.SomeEvent = MyHandler;  // not okay, must use += instead

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


4

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

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

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


4

เพื่อทำความเข้าใจความแตกต่างคุณสามารถดู 2 ตัวอย่างนี้

ตัวอย่างกับ Delegates (การดำเนินการในกรณีนี้คือผู้รับมอบสิทธิ์ประเภทหนึ่งที่ไม่ส่งคืนค่า)

public class Animal
{
    public Action Run {get; set;}

    public void RaiseEvent()
    {
        if (Run != null)
        {
            Run();
        }
    }
}

ในการใช้ผู้รับมอบสิทธิ์คุณควรทำสิ่งนี้

Animale animal= new Animal();
animal.Run += () => Console.WriteLine("I'm running");
animal.Run += () => Console.WriteLine("I'm still running") ;
animal.RaiseEvent();

รหัสนี้ใช้งานได้ดี แต่คุณอาจมีจุดอ่อนบางประการ

ตัวอย่างเช่นถ้าฉันเขียนสิ่งนี้

animal.Run += () => Console.WriteLine("I'm running");
animal.Run += () => Console.WriteLine("I'm still running");
animal.Run = () => Console.WriteLine("I'm sleeping") ;

ด้วยบรรทัดสุดท้ายของรหัสฉันได้ลบล้างพฤติกรรมก่อนหน้านี้เพียงหนึ่งรายการที่ขาดหายไป+(ฉันใช้+แทน+=)

อีกจุดที่อ่อนแอคือระดับที่ใช้ของคุณทุกAnimalระดับสามารถเพิ่มเพียงแค่เรียกมันว่าRaiseEventanimal.RaiseEvent()

เพื่อหลีกเลี่ยงจุดอ่อนนี้คุณสามารถใช้eventsใน c #

คลาส Animal ของคุณจะเปลี่ยนไปในลักษณะนี้

public class ArgsSpecial :EventArgs
   {
        public ArgsSpecial (string val)
        {
            Operation=val;
        }

        public string Operation {get; set;}
   } 



 public class Animal
    {
       public event EventHandler<ArgsSpecial> Run = delegate{} //empty delegate. In this way you are sure that value is always != null because no one outside of the class can change it

       public void RaiseEvent()
       {  
          Run(this, new ArgsSpecial("Run faster"));
       }
    }

เพื่อโทรหาเหตุการณ์

 Animale animal= new Animal();
 animal.Run += (sender, e) => Console.WriteLine("I'm running. My value is {0}", e.Operation);
 animal.RaiseEvent();

ความแตกต่าง:

  1. คุณไม่ได้ใช้ทรัพย์สินสาธารณะ แต่เป็นฟิลด์สาธารณะ (โดยมีเหตุการณ์ที่คอมไพเลอร์ปกป้องฟิลด์ของคุณจากการเข้าถึงที่ไม่ต้องการ)
  2. ไม่สามารถกำหนดกิจกรรมได้โดยตรง ในกรณีนี้คุณไม่สามารถทำข้อผิดพลาดก่อนหน้านี้ที่ฉันได้แสดงให้เห็นด้วยการลบล้างพฤติกรรม
  3. ไม่มีใครนอกชั้นเรียนของคุณสามารถยกเหตุการณ์ได้
  4. เหตุการณ์สามารถรวมอยู่ในการประกาศอินเทอร์เฟซในขณะที่ฟิลด์ไม่สามารถรวมได้

หมายเหตุ

EventHandler ประกาศเป็นผู้รับมอบสิทธิ์ต่อไปนี้:

public delegate void EventHandler (object sender, EventArgs e)

ต้องใช้ผู้ส่ง (ประเภทวัตถุ) และอาร์กิวเมนต์เหตุการณ์ ผู้ส่งเป็นโมฆะหากมาจากวิธีการคงที่

คุณสามารถใช้EventHAndlerแทนตัวอย่างนี้ที่ใช้EventHandler<ArgsSpecial>

อ้างอิงที่นี่สำหรับเอกสารเกี่ยวกับ EventHandler


3

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

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

  • เพื่อให้เมธอดสามารถใช้รูปแบบ 'template method' ที่เรียบง่าย (เช่นPredicateและActionผู้รับมอบสิทธิ์จะถูกส่งต่อไปยังคลาสคอลเลกชัน. Net ทั่วไป)
  • หรือเพื่อให้คลาสสามารถทำการ 'เรียกกลับ' ได้ (โดยทั่วไปจะเป็นการโทรกลับไปยังเมธอดของคลาสที่สร้างขึ้น)

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

ฉันมักจะไม่ใช้เหตุการณ์ แต่ที่ฉันใช้เหตุการณ์ฉันใช้มันสำหรับตัวเลือกในการส่งสัญญาณเหตุการณ์ไปยังศูนย์ลูกค้าหนึ่งรายหรือมากกว่าที่อาจสนใจกล่าวคือเมื่อมันสมเหตุสมผลว่าคลาส (เช่นSystem.Windows.Formคลาส) ควรมีอยู่และรันไม่ว่าจะมีไคลเอ็นต์หรือไม่ก็ตาม เพิ่มตัวจัดการเหตุการณ์ลงในเหตุการณ์ (เช่นมีเหตุการณ์ 'วางเมาส์' แบบฟอร์มอยู่ แต่เป็นทางเลือกว่าไคลเอนต์ภายนอกรายใดสนใจที่จะติดตั้งตัวจัดการเหตุการณ์ลงในเหตุการณ์นั้นหรือไม่)


2

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


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


คุณช่วยอธิบายรายละเอียดเกี่ยวกับเรื่องนี้ในขณะที่ฉันใช้ประโยชน์จากความเท่าเทียมใน UI ด้วยหรือไม่? ตัวอย่างที่ดีก็พอเพียง .... ขอบคุณ

1

ความแตกต่างระหว่างงานอีเวนต์และผู้ได้รับมอบหมายนั้นเล็กกว่าที่คิดไว้เยอะ .. ฉันเพิ่งโพสต์วิดีโอ YouTube สั้น ๆ ในหัวข้อนี้: https://www.youtube.com/watch?v=el-kKK-7SBU

หวังว่านี่จะช่วยได้!


2
ยินดีต้อนรับสู่ Stack Overflow! ในขณะนี้อาจตอบคำถามในทางทฤษฎีได้ แต่ควรรวมส่วนสำคัญของคำตอบไว้ที่นี่และระบุลิงก์สำหรับการอ้างอิง
GhostCat

1

หากเราใช้เฉพาะผู้รับมอบสิทธิ์แทนเหตุการณ์ผู้สมัครสมาชิกมีโอกาสที่จะโคลน () ให้เรียกใช้ () ผู้รับมอบสิทธิ์ตามที่แสดงด้านล่างในภาพ ซึ่งไม่ถูกต้อง.

ใส่คำอธิบายภาพที่นี่

นั่นคือความแตกต่างหลักของงาน b / w และ delegate ผู้สมัครสมาชิกมีสิทธิเพียงอย่างเดียวคือรับฟังเหตุการณ์

คลาส ConsoleLog กำลังสมัครบันทึกเหตุการณ์ผ่าน EventLogHandler

public class ConsoleLog
{
    public ConsoleLog(Operation operation)
    {
        operation.EventLogHandler += print;
    }

    public void print(string str)
    {
        Console.WriteLine("write on console : " + str);
    }
}

คลาส FileLog กำลังสมัครบันทึกเหตุการณ์ผ่าน EventLogHandler

public class FileLog
{
    public FileLog(Operation operation)
    {
        operation.EventLogHandler += print;
    }

    public void print(string str)
    {
        Console.WriteLine("write in File : " + str);
    }
}

คลาสปฏิบัติการกำลังเผยแพร่เหตุการณ์บันทึก

public delegate void logDelegate(string str);
public class Operation
{
    public event logDelegate EventLogHandler;
    public Operation()
    {
        new FileLog(this);
        new ConsoleLog(this);
    }

    public void DoWork()
    {
        EventLogHandler.Invoke("somthing is working");
    }
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.