.net组件开发系列(—)之武术系列 马步功
.net组件开发系列(—)之武术系列
1。马步功之基本功
在众多的武术中。大家都说自古武术出少林。为什么少林总是独当一面呢。少林练功从基本功打起。有了好马步功。才能有威力无比的金刚指,才有以柔克刚的武当张三丰的太极,我这个系列将,与大家一起练练马步功。为日后的成为武林高手作好准备,如果是你是一个武林高手,你可以闪人了。呵呵!!
本节中。将围着以下这几个问题来讲述。
a.属性的结构,属性与域的区别,为什么使用属性不使用域.命名规则。虚似属性及重载属性,属性的持久性
b.事件,事件处理程序,事件源,事件接收者,事件与委托的关系,委托,声明委托,使用委托,定义事件,使用事件,事件委托
c.元数据attribute:设计期attribute ,解析期attribute,类级别的attribute,
a1.1 属性结构:
先出示例:
private string carNO;
public string CarNO{
get{
return carNO;
}
set{
carNo=value;
}
}
}
编译器将把get,set中的内容转成属性访问操作的方法.获取对象(getter)用于取属性值,设置对象(setter)给属性赋值.
那个value是一个给setter的隐参数;
使用属性:Car c=new Car(); c.CarNo="H3263";
属性可以同时定义获取操作和设置操作或定义其中一个,尽管CLR允许只写属性,但.net框架设计准则不鼓励这样做。
如果组件需要只写属性,应该实现一个方法取代属性来提供相同的功能。而且,属性可以具有任何访问级别,如。private,public,protected 等等.
然而,在我们日常的开发组件中,经常要一些能够override的属性,使得派生类去改变其逻辑。方便其他人去扩展.如何做呢?
这时,虚拟属性就出台了。。
虚似属性。
建立一个虚似属性,必须在该属性第一次被声明的类中标记它,在C#中使用virtual关键字。
private string carNO;
public virtual string CarNO
{
get{ return carNO;}
set{ carNO=value;}
}
}
如何来重写其属性值呢。
{
public override string CarNO
{
get{ return base.CarNO}
}
set{
if(CarNO.indexof("H")<0)
{
Throw New Exception("不是现代小汽车");
}
base.CarNO="H2658";
}
}
注意点:如果两种属性访问都在基类中定义,就必须在子类中重写这两个访问操作。如果只想重字其中一个访问操作。可以让
另一个访问操作来委托基类。象例子中的CarNO属性的获取操作一样.
虚似属性还与版本有关系。一量定义了虚拟属性,就发须在其以后的组件的版本中用virtual标记这个属性。否则,将破坏现有的继承类。
属性还有一个可喜的操作。就是验证。。
如果属性是非法的。则抛出异常,在上一例子中,当检查不到包含"H"标志时,抛出”不是现代小汽车“的异常.
a1.2属性命名准则。
》用名词或名词短语作为属性名,
》把每个属性名的第一个字母大写并把后面的每个单词的首字母大写,如ViewState,BorderColor
a1.3 属性与域。
为什么使用属性不使用域呢?
我们都知道,面向对象其中之一是要求封装组件数据,使用属性就恰好就有这一点。
还有如下优点:
》数据隐藏:属性的存储和实现对用户是不可见的。
》验证:设置操作时,可以自定义验证。
》可以被子类重写。
》数据绑定 :
示例:绑定到属性
void Page_Load(Object sender, EventArgs e) {
Page.DataBind();
}
string custID{
get {
return "ALFKI";
}
}
int orderCount{
get {
return 11;
}
}
<body>
<h3><font face="宋体">到页属性的数据绑定</font></h3>
<form runat=server>
客户:<b><%# custID %></b><br>
未结的订单:<b><%# orderCount %></b>
</form>
</body>
》设计器支持:设计时属性 (Attribute) 向可视设计工具提供有价值的信息,所以它们对在设计时正确显示您的控件及其成员, 简明的说,就是在选择了一个组件属性时,该组件的属性将显示在属性浏览器中。
如图:
详细请看:http://msdn2.microsoft.com/zh-cn/library/tk67c2t8(VS.80).aspx
》版本化.因为属性的实现对用户来说是不可见的,用户可以在不破坏兼容的前提下修改将来的版本实现.
a1.4属性的持久化
网页是基于无状态机制的,Response后就不管理保存页面内容的状态,ASP.net提供ViewState机制来保存页面的状态
使用ViewSate来保存属性,使之持久化
例:
public virtual string CarNO
{
get{ return (string)ViewState["carNO"];}
set{ ViewState["carNO"]=value;}
}
}
b1.1事件及事件处理程序的概念
{
在面向对象理论中,一个对象(类的实例)可以有属性(property,获取或设置对象的状态)、方法(method,对象可以做的动作)等成员外,还有事件(event)。所谓事件,是对象内部状态发生了某些变化、或者对象做某些动作时(或做之前、做之后),向外界发出的通知。打个比方就是,对象“张三”肚子疼了,然后他站在空地上大叫一声“我肚子疼了!”事件就是这个通知。
那么,相对于对象内部发出的事件通知,外部环境可能需要应对某些事件的发生,而做出相应的反应。接着上面的比方,张三大叫一声之后,救护车来了把它接到医院(或者疯人院,呵呵,开个玩笑)。外界因应事件发生而做出的反应(具体到程序上,就是针对该事件而写的那些处理代码),称为事件处理程序(event handler)。
事件处理程序必须和对象的事件挂钩后,才可能会被执行。否则,孤立的事件处理程序不会被执行。另一方面,对象发生事件时,并不一定要有相应的处理程序。就如张三大叫之后,外界环境没有做出任何反应。也就是说,对象的事件和外界对该对象的事件处理之间,并没有必然的联系,需要你去挂接。
首先区分“事件”和“事件处理程序”这两个概念。事件是隶属于对象(类)本身的,事件处理程序是外界代码针对对象的事件做出的反应。事件,是对象(类)的设计者、开发者应该完成的;事件处理程序是外界调用方需要完成的。简单的说,事件是“内”;事件处理程序是“外”。
}
[这段文字来自joycode上的破宝]
事件与委托的关系
通常,触发事件的对象被事件发送者(Event Sender)调用:捕获处理事件的对象被事件接收者(Event Receiver)调用。在事件通信中,事件的发送者不知道哪个对象或者方法将要去接收/处理发送过去的事件。因而在事件源和事件接收者之间就需要一个中间人存在,这个中间人就叫委托.在使用事件的有效范围里,委托提供一种机制,在事件引发时为类指示要调用的方法。当事件引发时,使用委托作为被调用方法的指针,修改事件的类就不需要了解作为观测程序的类的任何信息
这里开始讲到了委托。有必要理解委托的概念:
委托的概念
[下面是我在听(俞晖 深入“委托和事件”)这节webcast所得到的]
MSDN官方定义:
委托申请和定义一个引用类型,用指定的签名封装方法,一个代理的实例可以封装静态或实例的方法,委托比较
象C++里的函数指针,但委托是一个类型安全的
CodeProject:
C#委托是一个回调的功能,但比一般的回调更加智能,可以定义了一组非常严格的参数,使得类的服务器端向类的客户端传递.
C#编程指南:
委托是一种引用方法类型。一旦为委托为分配了方法。
委托将与该方法具有完全相同的行为。委托方法的使用可以象其他任何方法一样,具有参数和返回值
委托实例的一个有趣且有用的属性是:它不知道也不关心它所封装的方法所属的类;它所关心的仅限于这些方法必须与委托的类型兼容,
这使委托非常适合于“匿名”调用
委托的实现,申明委托,实现委托
即然,我们知道了委托,如何使委托呢。
实现步骤如下:
示例:
public class DelegateSample
{
public void Hello(string name)
{
Console.WriteLine("Hello , "+name);
}
}
public class MainDemo
{
public static void Main(String[]args)
{
DelegateSample ds=new DelegateSample();
MyDelegate del=new MyDelegateSample(ds.Hello);
del("suiqirui19872005");
}
}
//运行结果Hello,suiqirui19872005
定义事件:
用event关键字和指示方法签名的委托对象来定义事件,这个事件的所有事件处理程序都得遵循该委托对象指示的方法签名。
public event EventHandler Click;
委托与事件实例:
有以下几步: 1. 申明委托, 2.定义呼叫者和调用的函数, 3.定义被呼叫者和具体实现的函数(被调用的函数)
示例:
c1.1元数据
元数据是一种二进制信息,用以对存储在公共语言运行库可移植可执行文件 (PE) 文件或存储在内存中的程序进行描述。将您的代码编译为 PE 文件时,便会将元数据插入到该文件的一部分中,而将代码转换为 Microsoft 中间语言 (MSIL) 并将其插入到该文件的另一部分中。在模块或程序集中定义和引用的每个类型和成员都将在元数据中进行说明。当执行代码时,运行库将元数据加载到内存中,并引用它来发现有关代码的类、成员、继承等信息。
设计期Attribute
对于控件在可视化设计器内正确运行是很重要的.设计器,属性浏览器和其它的设计期元素使用由设计期attribute提供的元数据的作用如下:
.显示属性和事件
.执行设计期的序列化
.把用来实现设计期的功能的类与控件或者属性类型关联起来
参考:http://zhf777.cnblogs.com/articles/300606.html
解析期attribute
解析期Attribute
用于被页面解析器解析.aspx页面的语法,为相应页面中的类生成代码
System.Web.UI.ControlBuilderAttribute
描述 : 将控件与自定义的控件生成器相关联
应用 : 类或属性
System.Web.UI.ParseChildrenAttribute
描述 : 通知解析器是否把控件标签内的嵌套内容翻译为属性或者子控件。
Control没有标记这个属性,意味着解析器把嵌套内容当作子控件。
WebControl标记为ParseChildren(true),因此解析器把嵌套内容当作属性
这个Attribute的两参数形式中的第二个参数是属性名,使用两参数形式时,把控件标签内的嵌套内容必须和第二个参数设定的属性一致
应用 : 控件
System.Web.UI.TemplateContainerAttribute
描述 : 将ITemplate属性的容器控件的类型通知解析器。解析器把这个类型作为数据绑定表达式中的Container的确切类型
应用 : 行为ITemplate的属性
类级别的attribute
下面的例子将一个名为MyDesigerAttribute的类级别设计其attribute应用到deControl类
public class deControl :Control
{
//.
}
第一次写总结性文章,况且水平限。写的不好,忘大家海含。
接下去我会写好的...