博文
.NET设计模式(18):迭代器模式(Iterator Pattern)(二)(2010-06-09 14:16:00)
摘要:.NET中的Iterator模式
在.NET下实现Iterator模式,对于聚集接口和迭代器接口已经存在了,其中IEnumerator扮演的就是迭代器的角色,它的实现如下:
public interface IEumerator
{
object Current
{
get;
}
bool MoveNext();
void Reset();
}
属性Current返回当前集合中的元素,Reset()方法恢复初始化指向的位置,MoveNext()方法返回值true表示迭代器成功前进到集合中的下一个元素,返回值false表示已经位于集合的末尾。能够提供元素遍历的集合对象,在.Net中都实现了IEnumerator接口。
IEnumerable则扮演的就是抽象聚集的角色,只有一个GetEnumerator()方法,如果集合对象需要具备跌代遍历的功能,就必须实现该接口。
public interface IEnumerable
{
IEumerator GetEnumerator();
}
下面看一个在.NET1.1下的迭代器例子,Person类是一个可枚举的类。PersonsEnumerator类是一个枚举器类。这个例子来自于[url]http://www.theserverside.net/[/url],被我简单的改造了一下。
public class Persons : IEnumerable
.NET设计模式(18):迭代器模式(Iterator Pattern)(一)(2010-06-09 14:15:00)
摘要:概述
在面向对象的软件设计中,我们经常会遇到一类集合对象,这类集合对象的内部结构可能有着各种各样的实现,但是归结起来,无非有两点是需要我们去关心的:一是集合内部的数据存储结构,二是遍历集合内部的数据。面向对象设计原则中有一条是类的单一职责原则,所以我们要尽可能的去分解这些职责,用不同的类去承担不同的职责。Iterator模式就是分离了集合对象的遍历行为,抽象出一个迭代器类来负责,这样既可以做到不暴露集合的内部结构,又可让外部代码透明的访问集合内部的数据。
意图
提供一种方法顺序访问一个聚合对象中各个元素, 而又不需暴露该对象的内部表示。[GOF 《设计模式》]
结构图
生活中的例子
迭代器提供一种方法顺序访问一个集合对象中各个元素,而又不需要暴露该对象的内部表示。在早期的电视机中,一个拨盘用来改变频道。当改变频道时,需要手工转动拨盘移过每一个频道,而不论这个频道是否有信号。现在的电视机,使用[后一个]和[前一个]按钮。当按下[后一个]按钮时,将切换到下一个预置的频道。想象一下在陌生的城市中的旅店中看电视。当改变频道时,重要的不是几频道,而是节目内容。如果对一个频道的节目不感兴趣,那么可以换下一个频道,而不需要知道它是几频道。
Iterator模式解说
在面向对象的软件设计中,我们经常会遇到一类集合对象,这类集合对象的内部结构可能有着各种各样的实现,但是归结起来,无非有两点是需要我们去关心的:一是集合内部的数据存储结构,二是遍历集合内部的数据。面向对象设计原则中有一条是类的单一职责原则,所以我们要尽可能的去分解这些职责,用不同的类去承担不同的职责。Iterator模式就是分离了集合对象的遍历行为,抽象出一个迭代器类来负责,这样既可以做到不暴露集合的内部结构,又可让外部代码透明的访问集合内部的数据。下面看一个简单的示意性例子,类结构图如下:
首先有一个抽象的聚集,所谓的聚集就是就是数据的集合,可以循环去访问它。它只有一个方法GetIterator()让子类去实现,用来获得一个迭代器对象。
/**//// <summary>
/// 抽象聚集
/// </summary>
public&nb......
.net 操作XML小结(2010-01-02 19:53:00)
摘要:一、简单介绍
using System.Xml;
//初始化一个xml实例
XmlDocument xml=new XmlDocument();
//导入指定xml文件
xml.Load(path);
xml.Load(HttpContext.Current.Server.MapPath("~/file/bookstore.xml"));
//指定一个节点
XmlNode root=xml.SelectSingleNode("/root");
//获取节点下所有直接子节点
XmlNodeList childlist=root.ChildNodes;
//判断该节点下是否有子节点
root.HasChildNodes;
//获取同名同级节点集合
XmlNodeList nodelist=xml.SelectNodes("/Root/News");
//生成一个新节点
XmlElement node=xml.CreateElement("News");
//将节点加到指定节点下,作为其子节点
root.AppendChild(node);
//将节点加到指定节点下某个子节点前
root.InsertBefore(node,root.ChildeNodes[i]);
//为指定节点的新建属性并赋值
node.SetAttribute("id","11111");
//为指定节点添加子节点
root.AppendChild(node);
//获取指定节点的指定属性值
string id=node.Attributes["id"].Value;
//获取指定节点中的文本
string content=node.InnerText;
//保存XML文件
string path=Server.MapPath("~/file/bookstore.xml");
xml.Save(path);
//or use :xml.Save(HttpContext.Current.Server.MapPath("~/file/bookstore.xml"));
......
ADO.net操作数据库总结(2010-01-02 19:41:00)
摘要:一.用SqlConnection连接SQL Server
1..加入命名空间
using System.Data.SqlClient;
2.连接数据库
SqlConnection myConnection = new SqlConnection();
myConnection.ConnectionString = "user id=sa;password=sinofindb;initial catalog=test;data source=127.0.0.1;Connect Timeout=30";
myConnection.Open();
改进(更通用)的方法:
string MySqlConnection="user id=sa;password=sinofindb;Database =test;data source=127.0.0.1;Connect Timeout=30";
SqlConnection myConnection = new SqlConnection(MySqlConnection);
myConnection.Open();
二。用OleDbConnection连接
1.加入命名空间
using System.Data.OleDb;
2.连接sql server
string MySqlConnection="Provider=SQLOLEDB;Data Source=localhost;Initial Catalog=test;Integrated Security=SSPI;";
SqlConnection myConnection = new SqlConnection(MySqlConnection);
myConnection.Open();
3.连接Access(可通过建立.udl文件获得字符串)
string MySqlConnection="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=c:db2000.mdb;
Persist Security Info=False;
4.连接Oracle(也可通过OracleConnection连接)
【摘录】.NET多线程编程(2009-12-31 11:08:00)
摘要: 在.NET中编写的程序将被自动的分配一个线程.让我们来看看用C#编程语言创建线程并且继续学习线程的知识。我们都知道.NET的运行时环境的主线程由Main ()方法来启动应用程序,而且.NET的编译语言有自动的垃圾收集功能,这个垃圾收集发生在另外一个线程里面,所有的这些都是后台发生的,让我们无法感觉到发生了什么事情.在这里默认的是只有一个线程来完成所有的程序任务,但是正如我们在第一篇文章讨论过的一样,有可能我们根据需要自己添加更多的线程让程序更好的协调工作。比如说我们的例子中,一个有用户输入的同时需要绘制图形或者完成大量的运算的程序,我们必须得增加一个线程,让用户的输入能够得到及时的响应,因为输入对时间和响应的要求是紧迫的,而另外一个线程负责图形绘制或者大量的运算。
.NET 基础类库的System.Threading命名空间提供了大量的类和接口支持多线程。这个命名空间有很多的类,我们将在这里着重讨论Thread这个类。
System.Threading.Thread类是创建并控制线程,设置其优先级并获取其状态最为常用的类。他有很多的方法,在这里我们将就比较常用和重要的方法做一下介绍:
Thread.Start():启动线程的执行;
Thread.Suspend():挂起线程,或者如果线程已挂起,则不起作用;
Thread.Resume():继续已挂起的线程;
Thread.Interrupt():中止处于 Wait或者Sleep或者Join 线程状态的线程;
Thread.Join():阻塞调用线程,直到某个线程终止时为止
Thread.Sleep():将当前线程阻塞指定的毫秒数;
Thread.Abort():以开始终止此线程的过程。如果线程已经在终止,则不能通过Thread.Start()来启动线程。
通过调用Thread.Sleep,Thread.Suspend或者Thread.Join可以暂停/阻塞线程。调用Sleep()和Suspend()方法意味着线程将不再得到CPU时间。这两种暂停线程的方法是有区别的,Sleep()使得线程立即停止执行,但是在调用Suspend()方法之......
Net中的反射使用入门(2009-12-31 11:05:00)
摘要: [转载]
MSDN:
ms-help://MS.VSCC.2003/MS.MSDNQTR.2003FEB.2052/cpguide/html/cpcondiscoveringtypeinformationatruntime.htm
提纲:
1、 什么是反射
2、 命名空间与装配件的关系
3、 运行期得到类型信息有什么用
4、 如何使用反射获取类型
5、 如何根据类型来动态创建对象
6、 如何获取方法以及动态调用方法
7、 动态创建委托
1、什么是反射
Reflection,中文翻译为反射。
这是.Net中获取运行时类型信息的方式,.Net的应用程序由几个部分:‘程序集(Assembly)’、‘模块(Module)’、‘类型(class)’组成,而反射提供一种编程的方式,让程序员可以在程序运行期获得这几个组成部分的相关信息,例如:
Assembly类可以获得正在运行的装配件信息,也可以动态的加载装配件,以及在装配件中查找类型信息,并创建该类型的实例。
Type类可以获得对象的类型信息,此信息包含对象的所有要素:方法、构造器、属性等等,通过Type类可以得到这些要素的信息,并且调用之。
MethodInfo包含方法的信息,通过这个类可以得到方法的名称、参数、返回值等,并且可以调用之。
诸如此类,还有FieldInfo、EventInfo等等,这些类都包含在System.Reflection命名空间下。
2、命名空间与装配件的关系
很多人对这个概念可能还是很不清晰,对于合格的.Net程序员,有必要对这点进行澄清。
命名空间类似与Java的包,但又不完全等同,因为Java的包必须按照目录结构来放置,命名空间则不需要。
装配件是.Net应用程序执行的最小单位,编译出来的.dll、.exe都是装配件。
装配件和命......
[摘录]C#.NET当中一些常见知识点和问题(2009-12-30 22:29:00)
摘要: 语言
C#
String 对象是不可改变的。每次使用 System.String 类中的方法之一时,都要在内存中创建一个新的字符串对象,这就需要为该新对象分配新的空间。在需要对字符串执行重复修改的情况下,与创建新的 String 对象相关的系统开销可能会非常昂贵。如果要修改字符串而不创建新的对象,则可以使用 System.Text.StringBuilder 类。例如,当在一个循环中将许多字符串连接在一起时,使用 StringBuilder 类可以提升性能。
通过用一个重载的构造函数方法初始化变量,可以创建 StringBuilder 类的新实例,正如以下示例中所阐释的那样。
[C#]
StringBuilder MyStringBuilder = new StringBuilder("Hello World!");
设置容量和长度
虽然 StringBuilder 对象是动态对象,允许扩充它所封装的字符串中字符的数量,但是您可以为它可容纳的最大字符数指定一个值。此值称为该对象的容量,不应将它与当前 StringBuilder 对象容纳的字符串长度混淆在一起。例如,可以创建 StringBuilder 类的带有字符串“Hello”(长度为 5)的一个新实例,同时可以指定该对象的最大容量为 25。当修改 StringBuilder 时,在达到容量之前,它不会为其自己重新分配空间。当达到容量时,将自动分配新的空间且容量翻倍。可以使用重载的构造函数......
Attribute在.NET编程中的应用(六)(2009-12-13 12:17:00)
摘要:(承上节) .NET Framework拦截机制的设计中,在客户端和对象之间,存在着多种消息接收器,这些消息接收器组成一个链表,客户端的调用对象的过程以及调用返回实行拦截,你可以定制自己的消息接收器,把它们插入了到链表中,来完成你对一个调用的前处理和后处理。那么调用拦截是如何构架或者说如何实现的呢?
在.NET中有两种调用,一种是跨应用域(App Domain),一种是跨上下文环境(Context),两种调用均通过中间的代理(proxy),代理被分为两个部分:透明代理和实际代理。透明代理暴露同对象一样的公共入口点,当客户调用透明代理的时候,透明代理把堆栈中的帧转换为消息(上一节提到的实现IMessage接口的对象),消息中包含了方法名称和参数等属性集,然后把消息传递给实际代理,接下去分两种情况:在跨应用域的情况下,实际代理使用一个格式化器对消息进行序列化,然后放入远程通道中;在跨上下文环境的情况下,实际代理不必知道格式化器、通道和Context拦截器,它只需要在向前传递消息之前对调用实行拦截,然后它把消息传递给一个消息接收器(实现IMessageSink的对象),每一个接收器都知道自己的下一个接收器,当它们对消息进行处理之后(前处理),都将消息传递给下一个接收器,一直到链表的最后一个接收器,最后一个接收器被称为堆栈创建器,它把消息还原为堆栈帧,然后调用对象,当调用方法结果返回的时候,堆栈创建器把结果转换为消息,传回给调用它的消息接收器,于是消息沿着原来的链表往回传,每个链表上的消息接收器在回传消息之前都对消息进行后处理。一直到链表的第一个接收器,第一个接收器把消息传回给实际代理,实际代理把消息传递给透明代理,后者把消息放回到客户端的堆栈中。从上面的描述我们看到穿越Context的消息不需要格式化,CLR使用一个内部的通道,叫做CrossContextChannel,这个对象也是一种消息接收器。
有几种消息接收器的类型,一个调用拦截可以在服务器端进行也可以在客户端进行,服务器端接收器拦截所有对服务器上下文环境中对象的调用,同时作一些前处理和后处理。客户端的接收器拦截所有外出客户端上下文环境的调用,同时也做一些前处理和后处理。服务器负责服务器端接收器的安装,拦截对服务器端上下文环境访问的接收器称为服务器上下文环境接收器,那些拦截调用实际对象的接收器是对象接收器。通......
Attribute在.NET编程中的应用(五)(2009-12-13 12:16:00)
摘要:
Attribute在拦截机制上的应用
从这一节开始我们讨论Attribute的高级应用,为此我准备了一个实际的例子:我们有一个订单处理系统,当一份订单提交的时候,系统检查库存,如果库存存量满足订单的数量,系统记录订单处理记录,然后更新库存,如果库存存量低于订单的数量,系统做相应的记录,同时向库存管理员发送邮件。为了方便演示,我们对例子进行了简化://Inventory.cs
using System;
using System.Collections;
namespace NiwalkerDemo
{
public class Inventory
{
private Hashtable inventory=new Hashtable();
public Inventory()
{
inventory["Item1"]=100;
inventory["Item2"]=200;
}
public bool Checkout(string product, int quantity)
{
int qty=GetQuantity(product);
return qty>=quantity;
}
public int GetQuantity(string product)
{
int qty=0;
if(inventory[product]!=null)
qty = (int)inventory[product];
return qty;
}
public void Update(string product, int quantity)
{
int qty=GetQuantity(product);
inventory[product]=qty-quantity;
}
}
}
......