- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章结合.net框架在C#派生类中触发基类事件及实现接口事件由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
在派生类中引发基类事件 以下简单示例演示了在基类中声明可从派生类引发的事件的标准方法。此模式广泛应用于 .NET Framework 类库中的 Windows 窗体类。 在创建可用作其他类的基类的类时,应考虑如下事实:事件是特殊类型的委托,只可以从声明它们的类中调用。派生类无法直接调用基类中声明的事件。尽管有时需要事件仅由基类引发,但在大多数情形下,应该允许派生类调用基类事件。为此,您可以在包含该事件的基类中创建一个受保护的调用方法。通过调用或重写此调用方法,派生类便可以间接调用该事件。 注意:不要在基类中声明虚拟事件,也不要在派生类中重写这些事件。C# 编译器无法正确处理这些事件,并且无法预知的该派生的事件的用户是否真正订阅了基类事件.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
|
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();
}
}
}
|
输出:
1
2
3
4
|
Received event. Shape area is now 10201.86
Drawing a circle
Received event. Shape area is now 49
Drawing a rectangle
|
实现接口事件 。
接口可声明事件。下面的示例演示如何在类中实现接口事件。实现接口事件的规则与实现任何接口方法或属性的规则基本相同。 在类中实现接口事件 在类中声明事件,然后在适当的区域调用该事件.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
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);
}
}
}
}
|
下面的示例演示如何处理以下的不常见情况:您的类是从两个以上的接口继承的,每个接口都含有同名事件)。在这种情况下,您至少要为其中一个事件提供显式接口实现。为事件编写显式接口实现时,必须编写 add 和 remove 事件访问器。这两个事件访问器通常由编译器提供,但在这种情况下编译器不能提供。 您可以提供自己的访问器,以便指定这两个事件是由您的类中的同一事件表示,还是由不同事件表示。例如,根据接口规范,如果事件应在不同时间引发,则可以将每个事件与类中的一个单独实现关联。在下面的示例中,订户将形状引用强制转换为 IShape 或 IDrawingObject,从而确定自己将会接收哪个 OnDraw 事件.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
|
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();
}
}
}
|
输出:
1
2
3
|
Sub1 receives the IDrawingObject event.
Drawing a shape.
Sub2 receives the IShape event.
|
最后此篇关于结合.net框架在C#派生类中触发基类事件及实现接口事件的文章就讲到这里了,如果你想了解更多关于结合.net框架在C#派生类中触发基类事件及实现接口事件的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我有一张 Excel 表格,用于更新玩家评分。 播放器 配售 初始化 1 2 3 4 金融评级 一个 1 2.0 1.000 0.018 0.016 0.014 2.007 D 2 -2.0 54.5
我有一个 map = std::map ,其中 myItemModel继承QAbstractItemModel . 我现在要合并所有 myItemModel合一myItemModel (其他所有元素模
我大量使用“do.call”来生成函数调用。例如: myfun <- "rnorm"; myargs <- list(n=10, mean=5); do.call(myfun, myargs); 但是
想象一下 InputStream 的以下变体: trait FutureInputStream { //read bytes asynchronously. Empty array means E
这是我的 C 代码: #include void sum(); int newAlphabet; int main(void) { sum();
我只是想选择类“.last”之后的每个元素。 HTML: 1 2 Jquery
我正在为一个项目构建一个 XML 反序列化器,我经常遇到这种类型的代码情况: var myVariable = ParseNDecimal(xml.Element("myElement")) == n
这是来自 Selecting the highest salary 的继续问题 假设有一个表 'wagetable' name lowhours highhours wage pri
我正在为我的程序创建一个战舰程序;该程序运行良好,但我试图确保当用户将坐标超出范围时,程序会说他们输入的坐标不正确。这是代码: #include #include void
我有一个函数,它为每种情况返回不同的 DWORD 值,如果出现错误。所以我有以下定义: #define ERR_NO_DB_CONNECTION 0x90000 #define ERR_DB_N
在派生类中引发基类事件以下简单示例演示了在基类中声明可从派生类引发的事件的标准方法。此模式广泛应用于 .NET Framework 类库中的 Windows 窗体类。在创建可用作其他类的基类的类时,应
我只是想知道这是否可能: use Modern::Perl; my @list = ('a' .. 'j'); map { func($_) } each(@list); sub func { m
我一直在使用 =IF(L2="","Active",IF(K2I2,"Late"))) 有效,但现在我需要检查 F 上的多个条件 专栏 我试过了 OR 函数 =IF(OR(F2="Scheduled"
我有 2 个命令,如下所示。 在视频中添加介绍图片 ffmpeg -y -loop 1 -framerate 10 -t 3 -i intro.png -i video.mp4 -filter_com
好的,我有这个公式可以根据名字和姓氏列表生成用户名。现在,虽然这可行,但我希望单元格改为引用我自己的 VBA 函数。但是,由于代码少得多,我仍然想使用原始公式。 我有这个公式: =SUBSTITUTE
我有两个 HAProxy 实例。两个实例都启用了统计信息并且工作正常。 我正在尝试将两个实例的统计信息合并为一个,以便我可以使用单个 HAProxy 来查看前端/后端统计信息。我试图让两个 hapro
我有一个 Observable,其中每个新值都应该引起一个 HTTP 请求。在客户端,我只关心最新的响应值;但是,我希望每个请求都能完成以进行监控/等。目的。 我目前拥有的是这样的: function
我的网站上有 TinyMCE 插件。在 TinyMCE 插件的 textarea 中添加图像时,我希望这些图像包含延迟加载。我网站的缩略图具有特定类型的延迟加载,其中 src 图像是灰色背景。根据用户
我希望合并润滑间隔,以便如果它们重叠,则从内部第一个时间获取最小值和从内部最后一个时间获取最大值并总结以创建一个跨越整个时间段的新间隔。这是一个reprex: library(lubridate, w
我有一个应用程序,它本质上是一个页眉、主要内容和一个始终可见的页脚。页脚可以改变大小,我想在页脚上方的主内容面板上放置一些工具。主要布局是用 flex 完成的,我阅读文档的理解是绝对定位通过相对于最近
我是一名优秀的程序员,十分优秀!