欧美大屁股bbbbxxxx,狼人大香伊蕉国产www亚洲,男ji大巴进入女人的视频小说,男人把ji大巴放进女人免费视频,免费情侣作爱视频

歡迎來到入門教程網(wǎng)!

C#教程

當(dāng)前位置:主頁 > 軟件編程 > C#教程 >

結(jié)合.net框架在C#派生類中觸發(fā)基類事件及實(shí)現(xiàn)接口事件

來源:本站原創(chuàng)|時(shí)間:2020-01-10|欄目:C#教程|點(diǎn)擊: 次

在派生類中引發(fā)基類事件
以下簡單示例演示了在基類中聲明可從派生類引發(fā)的事件的標(biāo)準(zhǔn)方法。此模式廣泛應(yīng)用于 .NET Framework 類庫中的 Windows 窗體類。
在創(chuàng)建可用作其他類的基類的類時(shí),應(yīng)考慮如下事實(shí):事件是特殊類型的委托,只可以從聲明它們的類中調(diào)用。派生類無法直接調(diào)用基類中聲明的事件。盡管有時(shí)需要事件僅由基類引發(fā),但在大多數(shù)情形下,應(yīng)該允許派生類調(diào)用基類事件。為此,您可以在包含該事件的基類中創(chuàng)建一個(gè)受保護(hù)的調(diào)用方法。通過調(diào)用或重寫此調(diào)用方法,派生類便可以間接調(diào)用該事件。
注意:不要在基類中聲明虛擬事件,也不要在派生類中重寫這些事件。C# 編譯器無法正確處理這些事件,并且無法預(yù)知的該派生的事件的用戶是否真正訂閱了基類事件。

namespace BaseClassEvents
{
  using System;
  using System.Collections.Generic;

  // Special EventArgs class to hold info about Shapes.
  public class ShapeEventArgs : EventArgs
  {
    private double newArea;

    public ShapeEventArgs(double d)
    {
      newArea = d;
    }
    public double NewArea
    {
      get { return newArea; }
    }
  }

  // Base class event publisher
  public abstract class Shape
  {
    protected double area;

    public double Area
    {
      get { return area; }
      set { area = value; }
    }
    // The event. Note that by using the generic EventHandler<T> event type
    // we do not need to declare a separate delegate type.
    public event EventHandler<ShapeEventArgs> ShapeChanged;

    public abstract void Draw();

    //The event-invoking method that derived classes can override.
    protected virtual void OnShapeChanged(ShapeEventArgs e)
    {
      // Make a temporary copy of the event to avoid possibility of
      // a race condition if the last subscriber unsubscribes
      // immediately after the null check and before the event is raised.
      EventHandler<ShapeEventArgs> handler = ShapeChanged;
      if (handler != null)
      {
        handler(this, e);
      }
    }
  }

  public class Circle : Shape
  {
    private double radius;
    public Circle(double d)
    {
      radius = d;
      area = 3.14 * radius * radius;
    }
    public void Update(double d)
    {
      radius = d;
      area = 3.14 * radius * radius;
      OnShapeChanged(new ShapeEventArgs(area));
    }
    protected override void OnShapeChanged(ShapeEventArgs e)
    {
      // Do any circle-specific processing here.

      // Call the base class event invocation method.
      base.OnShapeChanged(e);
    }
    public override void Draw()
    {
      Console.WriteLine("Drawing a circle");
    }
  }

  public class Rectangle : Shape
  {
    private double length;
    private double width;
    public Rectangle(double length, double width)
    {
      this.length = length;
      this.width = width;
      area = length * width;
    }
    public void Update(double length, double width)
    {
      this.length = length;
      this.width = width;
      area = length * width;
      OnShapeChanged(new ShapeEventArgs(area));
    }
    protected override void OnShapeChanged(ShapeEventArgs e)
    {
      // Do any rectangle-specific processing here.

      // Call the base class event invocation method.
      base.OnShapeChanged(e);
    }
    public override void Draw()
    {
      Console.WriteLine("Drawing a rectangle");
    }

  }

  // Represents the surface on which the shapes are drawn
  // Subscribes to shape events so that it knows
  // when to redraw a shape.
  public class ShapeContainer
  {
    List<Shape> _list;

    public ShapeContainer()
    {
      _list = new List<Shape>();
    }

    public void AddShape(Shape s)
    {
      _list.Add(s);
      // Subscribe to the base class event.
      s.ShapeChanged += HandleShapeChanged;
    }

    // ...Other methods to draw, resize, etc.

    private void HandleShapeChanged(object sender, ShapeEventArgs e)
    {
      Shape s = (Shape)sender;

      // Diagnostic message for demonstration purposes.
      Console.WriteLine("Received event. Shape area is now {0}", e.NewArea);

      // Redraw the shape here.
      s.Draw();
    }
  }

  class Test
  {

    static void Main(string[] args)
    {
      //Create the event publishers and subscriber
      Circle c1 = new Circle(54);
      Rectangle r1 = new Rectangle(12, 9);
      ShapeContainer sc = new ShapeContainer();

      // Add the shapes to the container.
      sc.AddShape(c1);
      sc.AddShape(r1);

      // Cause some events to be raised.
      c1.Update(57);
      r1.Update(7, 7);

      // Keep the console window open in debug mode.
      System.Console.WriteLine("Press any key to exit.");
      System.Console.ReadKey();
    }
  }
}

輸出:

    Received event. Shape area is now 10201.86
    Drawing a circle
    Received event. Shape area is now 49
    Drawing a rectangle


實(shí)現(xiàn)接口事件

接口可聲明事件。下面的示例演示如何在類中實(shí)現(xiàn)接口事件。實(shí)現(xiàn)接口事件的規(guī)則與實(shí)現(xiàn)任何接口方法或?qū)傩缘囊?guī)則基本相同。
在類中實(shí)現(xiàn)接口事件
在類中聲明事件,然后在適當(dāng)?shù)膮^(qū)域調(diào)用該事件。

namespace ImplementInterfaceEvents
{
  public interface IDrawingObject
  {
    event EventHandler ShapeChanged;
  }
  public class MyEventArgs : EventArgs 
  {
    // class members
  }
  public class Shape : IDrawingObject
  {
    public event EventHandler ShapeChanged;
    void ChangeShape()
    {
      // Do something here before the event…

      OnShapeChanged(new MyEventArgs(/*arguments*/));

      // or do something here after the event. 
    }
    protected virtual void OnShapeChanged(MyEventArgs e)
    {
      if(ShapeChanged != null)
      {
        ShapeChanged(this, e);
      }
    }
  }

}

下面的示例演示如何處理以下的不常見情況:您的類是從兩個(gè)以上的接口繼承的,每個(gè)接口都含有同名事件)。在這種情況下,您至少要為其中一個(gè)事件提供顯式接口實(shí)現(xiàn)。為事件編寫顯式接口實(shí)現(xiàn)時(shí),必須編寫 add 和 remove 事件訪問器。這兩個(gè)事件訪問器通常由編譯器提供,但在這種情況下編譯器不能提供。
您可以提供自己的訪問器,以便指定這兩個(gè)事件是由您的類中的同一事件表示,還是由不同事件表示。例如,根據(jù)接口規(guī)范,如果事件應(yīng)在不同時(shí)間引發(fā),則可以將每個(gè)事件與類中的一個(gè)單獨(dú)實(shí)現(xiàn)關(guān)聯(lián)。在下面的示例中,訂戶將形狀引用強(qiáng)制轉(zhuǎn)換為 IShape 或 IDrawingObject,從而確定自己將會接收哪個(gè) OnDraw 事件。

namespace WrapTwoInterfaceEvents
{
  using System;

  public interface IDrawingObject
  {
    // Raise this event before drawing
    // the object.
    event EventHandler OnDraw;
  }
  public interface IShape
  {
    // Raise this event after drawing
    // the shape.
    event EventHandler OnDraw;
  }


  // Base class event publisher inherits two
  // interfaces, each with an OnDraw event
  public class Shape : IDrawingObject, IShape
  {
    // Create an event for each interface event
    event EventHandler PreDrawEvent;
    event EventHandler PostDrawEvent;

    object objectLock = new Object();

    // Explicit interface implementation required.
    // Associate IDrawingObject's event with
    // PreDrawEvent
    event EventHandler IDrawingObject.OnDraw
    {
      add
      {
        lock (objectLock)
        {
          PreDrawEvent += value;
        }
      }
      remove
      {
        lock (objectLock)
        {
          PreDrawEvent -= value;
        }
      }
    }
    // Explicit interface implementation required.
    // Associate IShape's event with
    // PostDrawEvent
    event EventHandler IShape.OnDraw
    {
      add
      {
        lock (objectLock)
        {
          PostDrawEvent += value;
        }
      }
      remove
      {
        lock (objectLock)
        {
          PostDrawEvent -= value;
        }
      }


    }

    // For the sake of simplicity this one method
    // implements both interfaces. 
    public void Draw()
    {
      // Raise IDrawingObject's event before the object is drawn.
      EventHandler handler = PreDrawEvent;
      if (handler != null)
      {
        handler(this, new EventArgs());
      }
      Console.WriteLine("Drawing a shape.");

      // RaiseIShape's event after the object is drawn.
      handler = PostDrawEvent;
      if (handler != null)
      {
        handler(this, new EventArgs());
      }
    }
  }
  public class Subscriber1
  {
    // References the shape object as an IDrawingObject
    public Subscriber1(Shape shape)
    {
      IDrawingObject d = (IDrawingObject)shape;
      d.OnDraw += new EventHandler(d_OnDraw);
    }

    void d_OnDraw(object sender, EventArgs e)
    {
      Console.WriteLine("Sub1 receives the IDrawingObject event.");
    }
  }
  // References the shape object as an IShape
  public class Subscriber2
  {
    public Subscriber2(Shape shape)
    {
      IShape d = (IShape)shape;
      d.OnDraw += new EventHandler(d_OnDraw);
    }

    void d_OnDraw(object sender, EventArgs e)
    {
      Console.WriteLine("Sub2 receives the IShape event.");
    }
  }


  public class Program
  {
    static void Main(string[] args)
    {
      Shape shape = new Shape();
      Subscriber1 sub = new Subscriber1(shape);
      Subscriber2 sub2 = new Subscriber2(shape);
      shape.Draw();

      // Keep the console window open in debug mode.
      System.Console.WriteLine("Press any key to exit.");
      System.Console.ReadKey();
    }
  }

}

輸出:

  Sub1 receives the IDrawingObject event.
  Drawing a shape.
  Sub2 receives the IShape event.

上一篇:深入解析C#中的泛型類與泛型接口

欄    目:C#教程

下一篇:C#中的delegate委托類型基本學(xué)習(xí)教程

本文標(biāo)題:結(jié)合.net框架在C#派生類中觸發(fā)基類事件及實(shí)現(xiàn)接口事件

本文地址:http://mengdiqiu.com.cn/a1/C_jiaocheng/6721.html

網(wǎng)頁制作CMS教程網(wǎng)絡(luò)編程軟件編程腳本語言數(shù)據(jù)庫服務(wù)器

如果侵犯了您的權(quán)利,請與我們聯(lián)系,我們將在24小時(shí)內(nèi)進(jìn)行處理、任何非本站因素導(dǎo)致的法律后果,本站均不負(fù)任何責(zé)任。

聯(lián)系QQ:835971066 | 郵箱:835971066#qq.com(#換成@)

Copyright © 2002-2020 腳本教程網(wǎng) 版權(quán)所有