Developing Microsoft ASP.NET Server Controls and Components :Component Programming Overview
Developing Microsoft ASP.NET Server Controls and Components
Part 1 :Component Programming Overview
Name Space
Syntax
C#:
Namespace
{
}
VB:
Namespace
End Namespace
Naming Guidelines
Prefixing namespace names with a company name or other well-established brand
Use a stable, recognized technology name at the second level of a hierarchical name.
Pascal case
Use plural namespace names if it is semantically appropriate.
Do not use the same name for a namespace and a class.
Examples
Design Guidelines
Class
Syntax
C#:
class identifier [: base-list] { class-body }[;]
VB:
Class name
[ Inherits classname ]
[ Implements interfacenames ]
[ statements ]
End Class
Naming Guidelines
Use a noun or noun phrase to name a class.
Use Pascal case.
Use abbreviations sparingly.
Do not use a type prefix
Do not use the underscore character (_)
The second part of the derived class's name should be the name of the base class.
Examples
Property
Syntax
C#:
set {accessor-body}
get {accessor-body}
VB:
Property varname ([ ByVal parameter list ]) [ As typename ]
Get
End Get
Set(ByVal value As typename )
End Set
End Property
VB用default关键字确定类的缺省属性
Remarks
如果基类的某个属性定义了两个property accessors,子类若要override该属性就必须override这两个accessor,如果只想override一个accessor的逻辑,那么可以把另一个accessor委派给基类来做。(base.PropertyName,MyBase.PropertyName)
write-only:只实现set accessor
read-only:只实现get accessor
Property & Method
若需要write-only的属性,应该用一个相同功能的方法来代替。
如果会造成大量系统开销,用方法来代替。
如果设置属性需要先后顺序,用方法来代替。
连续调用属性会产生不同的结果,用方法代替。
Naming Guidelines
用名词或者名词短语
用Pascal格式,不要用Hungarian表示法
考虑用与属性的基础类型相同的名称创建属性:public Color BackColor
Design Guidlines
当属性的逻辑数据成员为数组时,请使用索引属性。将索引属性命名为 Item,除非存在对于用户来说更直观的名称。并且仅为每个类使用一个索引属性。并使其成为该类的默认索引属性。(C#只允许默认索引,VB允许default关键字)
在使用 set 访问器访问属性时,请在更改属性前保留属性的值。这将确保在 set 访问器引发异常时不会丢失数据。
允许以任何顺序设置属性。对于其他属性,属性应当是无状态的。
如果您确实有相关属性(如 DataSource 和 DataMember),则应考虑实现 ISupportInitialize 接口。
Method
Syntax
C#:
参数的关键字
params /ref / out
VB:
Sub name [(arglist)] [ Implements interface.definedname ]
[ statements ]
[ Exit Sub ]
[ statements ]
End Sub
Function name[(arglist)] [ As type ] [ Implements interface.definedname ]
[ statements ]
[ Exit Function ]
[ statements ]
End Function
参数关键字
ParamArray,Optional,ByVal, ByRef, As
Naming Guidelines
用动作的动词或者动词短语
方法名用Pascal格式
参数名描述参数含义,而非参数类型
参数名用Camel格式,不要用Hungarian表示法
不要用系统保留参数名作为参数的名字
Design Guidelines
如果使用方法重载, 对方法参数使用一致的排序和命名模式。
使用方法重载,不要使用默认参数。比如IndexOf,而不是在Indexof方法中给startIndex一个默认值,而是使用了重载。在一个重载方法系列中,复杂方法应当使用参数名来指示从简单方法中假定的默认状态发生的更改。
int String.IndexOf (String name);
int String.IndexOf (String name, int startIndex);
组中唯一的虚拟方法应该是具有最完整参数的方法
无效的参数引发System.ArgumentException(或子类)异常
Event
Syntax
C#:
event type declarator;
or
event type member-name {accessor-declarations};
VB:
Event eventname[(arglist)]
[Implements interfacename.interfaceeventname ]
Examples
Declaring an event:
event MyDelegate MyEvent;
Using a hash table to store event instances:
private Hashtable eventTable = new Hashtable();
public event MyDelegate1 Event1
{
add
{
eventTable["Event1"]=(MyDelegate1)eventTable["Event1"] + value;
}
remove
{
eventTable["Event1"] = (MyDelegate1)eventTable["Event1"] - value;
}
}
Delegate
C#:
delegate result-type identifier ([formal-parameters]);
VB:
Delegate [ Function ] name [([ arglist ])] As type
Delegate是类,用来封装具有特定签名和返回类型的方法,有自己的属性和方法。委托就等效于一个类型安全函数指针或一个回调
宣布一个delegate类型的变量,Net Framework编译器会自动生成一个从System.MulticastDelegate派生的类(不是从System.Delegate派生),
System.MulticastDelegate派生自System.Delegate,程序员没有权限直接从System.Delegate/MulticastDelegate 创建派生类,只有编译器和Run Time才能这么做。.NET Framework中,System.MulticastDelegate是delegate类型的基类。当MulticastDelegate的实例被调用时,绑定到它的函数会依次被调用。
任何返回值是void的委派都是多重委派,多重委派是事件处理的基本。
可以定义静态delegate或者delegate类型的参数避免应用delegate动态调用函数时的初始化过程。
Name Space System下的几个Delegate
AssemblyLoadEventHandler
AsyncCallback
CrossAppDomainDelegate
EventHandler
ResolveEventHandler
UnhandledExceptionEventHandler
Naming Guidelines
返回值为void.
指定两个名为 sender 和 e 的参数。sender 参数表示引发事件的对象。sender 参数始终是 object 类型的,e为特定的事件类
自定义的事件类应该用EventArgs后缀
用Pascal格式. 不要用Hungarian表示法
对事件处理程序名称使用 EventHandler 后缀
Event名字用动词形式,用动词进行时表示pre-event, 动词过去式表示post-event。(不要用BeforeXxx / AfterXxx的格式)
不要在类型的事件声明上使用前缀或者后缀。(用 Close,而不要用OnClose)
通常提供一个名字为OnXxx的protected方法供子类overridden,为派生的类提供处理事件的方式。该方法只有一个event参数e, 因为sender总是实例本身。使用override来为派生的类提供处理事件的方式。
Raising an Event,Step By Step
1:定义一个System.EventArgs派生的类,并且名字应该以EventArgs为后缀
public class LowChargeEventArgs : EventArgs {...}
2:定义一个后缀名为EventHandler的delegate
public delegate void LowChargeEventHandler(object sender,
LowChargeEventArgs e);
3:以Event声明一个事件,类型2中定义的delegate
(或者直接用System.EventHandler)
public event LowChargeEventHandler LowCharge;
4:定义一个前缀为On的virtual方法,检查是否用对象订阅事件,有的话通过delegate调用绑定到这个delegate的函数。(只有一个参数EventArgs e)通过该方法触发事件。
protected virtual void OnLowCharge(LowChargeEventArgs e) {
if (LowCharge != null) {
LowCharge(this, e);
}
}
编译器发现event关键字,会自动生成三个成员:
private LowChargeEventHandler LowCharge = null;
public void Add_LowCharge(LowChargeEventHandler handler) {
LowCharge =
(LowChargeEventHandler)Delegate.Combine(LowCharge, handler);
}
public void Remove_LowCharge(LowChargeEventHandler handler) {
LowCharge =
(LowChargeEventHandler)Delegate.Remove(LowCharge, handler);
}
自动生成的两个方法的存取权限和定义的event存取权限相同,但是即使这两个方法是public的他们也不能直接从客户端代码访问,客户端代码只能以重载过的操作符+=/-=或者AddHandler/RemoveHandler来订阅事件或者取消订阅
Remarks
EventArgs类不包含任何数据
如果一个类定义了太多的event,每一个event都分配一个delegate存储成本太大,因为即使没有event handlers,每个delegate字段都会消费内存。事件属性由带有事件访问器的事件声明组成,事件访问器是您定义的方法,用以允许事件委托实例添加到存储数据结构或从存储数据结构移除。事件属性要比事件字段慢, Windows 窗体控件和 ASP.NET 服务器控件使用事件属性而不是事件字段。
.NET Framework提供了一个工具类System.ComponentModel.EventHandlerList用来存储delegate数据结构。
Design Guidlines
应当假定事件处理程序可能包含任何代码。返回引发事件的点时不要假定有关对象状态的任何事情。
使用或扩展 System.ComponentModel.CancelEventArgs 类,使开发人员能够控制对象的事件。
Cancel events are not appropriate in cases where the developer would cancel the operation and return an exception. In these cases, you should raise an exception inside of the event handler in order to cancel.
posted on 2003-10-28 18:47:00 by microhelper 评论(1) 阅读(2383)
