在创建可用作其他类的基类的类时,应考虑如下事实:事件是特殊类型的委托,只可以从声明它们的类中调用。派生类无法直接调用基类中声明的事件。尽管有时需要事件仅由基类引发,但在大多数情形下,应该允许派生类调用基类事件。(注:之所以可以在父类引发,是因为运行时状态下父类只是指向子类的指针,这样即使给事件传递参数this,也是子类而不是父类)为此,您可以在包含该事件的基类中创建一个受保护的调用方法。通过调用或重写此调用方法,派生类便可以间接调用该事件。
关键:1、基类中定义事件、并且定义虚方法触发事件,例子中OnShapeChanged()
2、子类可以通过调用或重写OnShapeChanged间接触发基类事件。
namespace
ConsoleApplication1{
class Program
{
static void Main(string[] args)
{
Circle c1 = new Circle();
ShapeContainer sc = new ShapeContainer();
// Add the shapes to the container.
sc.AddShape(c1);
// Cause some events to be raised.
c1.Update(57);
}
}
public abstract class Shape
{
// 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;
// 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.
protected virtual void OnShapeChanged(ShapeEventArgs e)
{
EventHandler<ShapeEventArgs> handle = ShapeChanged;
if (handle != null)
{ handle(this, e); }
}
public abstract void Draw();
}
public class Circle : Shape
{
public override void Draw()
{
// throw new NotImplementedException();
}
protected override void OnShapeChanged(ShapeEventArgs e)
{ // Call the base class event invocation method.
base.OnShapeChanged(e);
}
public void Update(double d)
{
OnShapeChanged(new ShapeEventArgs(100));
}
}
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();
}
}
public class ShapeEventArgs : EventArgs
{
private double newArea;
public ShapeEventArgs(double d)
{
newArea = d;
}
public double NewArea
{
get { return newArea; } } }}
联系客服