2008年10月21日星期二

c#2.0泛型学习

根据微软的视频教程"跟我一起学Visual Studio 2005C#语法篇"来学,因为里面有比较多的代码示例,学起来比较容易好理解

1.未使用泛型的Stack类

1using System;
2
3public class Stack
4{
5 readonly int m_Size;
6 int m_StackPointer = 0;
7 object[] m_Items;
8 public Stack(): this(100)
9 { }
10 public Stack(int size)
11 {
12 m_Size = size;
13 m_Items = new object[m_Size];
14 }
15 public void Push(object item)
16 {
17 if (m_StackPointer >= m_Size)
18 throw new StackOverflowException();
19
20 m_Items[m_StackPointer] = item;
21 m_StackPointer++;
22 }
23 public object Pop()
24 {
25 m_StackPointer--;
26 if (m_StackPointer >= 0)
27 {
28 return m_Items[m_StackPointer];
29 }
30 else
31 {
32 m_StackPointer = 0;
33 throw new InvalidOperationException("Cannot pop an empty stack");
34 }
35 }
36}
37
2.使用泛型的类


1using System;
2
3public class Stack
4{
5 readonly int m_Size;
6 int m_StackPointer = 0;
7 T[] m_Items;
8 public Stack()
9 : this(100)
10 {
11 }
12 public Stack(int size)
13 {
14 m_Size = size;
15 m_Items = new T[m_Size];
16 }
17 public void Push(T item)
18 {
19 if (m_StackPointer >= m_Size)
20 throw new StackOverflowException();
21
22 m_Items[m_StackPointer] = item;
23 m_StackPointer++;
24 }
25 public T Pop()
26 {
27 m_StackPointer--;
28 if (m_StackPointer >= 0)
29 {
30 return m_Items[m_StackPointer];
31 }
32 else
33 {
34 m_StackPointer = 0;
35 //throw new InvalidOperationException("Cannot pop an empty stack");
36 return default(T);
37 }
38 }
39}
40
41public class Stack1 : Stack
42{
43
44}
45
下为PDF文档,我感觉挺好的,很简单,我听的懂就是好的
/Clingingboy/one.pdf

多个泛型
1class Node
2{
3 public K Key;
4 public T Item;
5 public Node NextNode;
6 public Node()
7 {
8 Key = default(K);
9 Item = default(T);
10 NextNode = null;
11 }
12 public Node(K key, T item, Node nextNode)
13 {
14 Key = key;
15 Item = item;
16 NextNode = nextNode;
17 }
18}
泛型别名

1using list = LinkedList;
泛型约束

1public class LinkedList where K : IComparable
2{
3 Node m_Head;
4 public LinkedList()
5 {
6 m_Head = new Node();
7 }
8 public void AddHead(K key, T item)
9 {
10 Node newNode = new Node(key, item, m_Head.NextNode);
11 m_Head.NextNode = newNode;
12 }
13
14 T Find(K key)
15 {
16 Node current = m_Head;
17 while (current.NextNode != null)
18 {
19 if (current.Key.CompareTo(key) == 0)
20 break;
21 else
22 current = current.NextNode;
23 }
24 return current.Item;
25 }
26
27}
28

1using System;
2using System.Collections.Generic;
3using System.Text;
4
5namespace VS2005Demo1
6{
7 public class MyBaseClassGeneric // sealed,static
8 {
9 }
10
11 interface IMyBaseInterface
12 {
13 void A();
14 }
15
16 internal class GenericClass where T : MyBaseClassGeneric,IMyBaseInterface
17 {
18
19 }
20
21 class GClass where K : MyBaseClassGeneric,IMyBaseInterface,new() where T : K
22 {
23
24 }
25
26 class GUClass where T : K where K : MyBaseClassGeneric,IMyBaseInterface, new()
27 {
28 GClass obj = new GClass();
29 }
30
31
32 不能将引用/值类型约束与基类约束一起使用,因为基类约束涉及到类#region 不能将引用/值类型约束与基类约束一起使用,因为基类约束涉及到类
33
34 //class A where T : struct,class
35 //{}
36
37 #endregion
38
39 不能使用结构和默认构造函数约束,因为默认构造函数约束也涉及到类#region 不能使用结构和默认构造函数约束,因为默认构造函数约束也涉及到类
40
41 //class A where T : struct,new()
42 //{}
43
44 #endregion
45
46 虽然您可以使用类和默认构造函数约束,但这样做没有任何价值#region 虽然您可以使用类和默认构造函数约束,但这样做没有任何价值
47
48 class A where T : new()
49 {
50 T obj = new T();
51 }
52
53 class TypeA
54 {
55 public TypeA() { }
56 }
57
58 class TestA
59 {
60 A obj = new A();
61 }
62
63 #endregion
64
65 可以将引用/值类型约束与接口约束组合起来,前提是引用/值类型约束出现在约束列表的开头#region 可以将引用/值类型约束与接口约束组合起来,前提是引用/值类型约束出现在约束列表的开头
66
67 class SClass where K : struct, IMyBaseInterface
68 { }
69
70 class CClass where K : class, IMyBaseInterface
71 { }
72
73 #endregion
74}
75

资料引用:http://www.knowsky.com/339311.html

C#编程--基础知识点

.NetFramework简介
.netframework运行于操作系统之上,提供良好的跨语言特性。
.netframework包含两个内容:公共语言运行时(CLR)和类库集(FCL)
MSIL微软中间语言。当编译.net支持的语言编写的代码的时候,输出的代码为MSIL
CLR又包含:通用语言规范(CLS:保证语言互操作性的一组规则)和公共类型系统(CTS:包含了.net支持的各语言间兼容的数据类型和功能)

--------------------------------------------------------------------------------

C#中的变量和常量
C#中的基本数据类型:
值类型和引用类型
值类型:简单类型、结构类型和枚举类型。
简单类型:整数类型、浮点类型、小数类型(decimal)和布尔类型等
sbyte是有符号的,相当java的byte型,范围-128~127
C#中byte是无符号的,范围0~255

--------------------------------------------------------------------------------

变量命名方法:
帕斯卡命名法和骆驼命名法
帕斯卡命名法:如果有多个单词组成,每个单词首字母大写
骆驼命名法:如果有多个单词组成,第一个单词全部小写,后面的单词大写

--------------------------------------------------------------------------------

C#中的常量:const与readonly两种
const声明的常量:叫静态常量,必须声明时就初始化,且只能用常数值初始化
readonly声明的常量:叫动态常量,可以在声明时不初始化,只能在构造函数中初始化,但必须每个构造函数中都要初始化;而且可以使用变量值初始化

class Test
{
const float PI = 3.1416f; //常量命名:全部大写
readonly float G;
public Test()
{
G = 9.80F;
}
public Test(float g) //每个构造函数中都要初始化;而且可以使用变量值初始化
{
G = g;
}
}

--------------------------------------------------------------------------------

C#中的装箱和拆箱
装箱:值类型转换成有引用类型
拆箱:引用类型转换成值类型
值类型:存在栈中
引用类型:在堆中存放对象的地址(即引用),对象本身存放在栈中
拆装箱允许值类型和引用类型相互处理

--------------------------------------------------------------------------------

C#语法

Switch()括号中可以是int ,char和string ,switch语句中的case语句冒号后什么都不写,可以不写break,其他情况一定要写break,否则报错

数组:五种声明方式
int []array;
array = new int[2];

//第二种声明方式
int []array1 = new int[2];

//第三种声明方式
int []array2 = {1,2,3};

//第四种声明方式
int []array3 = new int[]{1,2,3};

//第五种声明方式
int []array4 = new int[3]{1,2,3};

//数组大小也可以是变量
int count = 3;
int []arr = new int[count];
--------------------------------------------------------------------------------

枚举:用有意义的字符去访问数据
public enum Contry:long //指定枚举类型,必须是整型,不写为int型
{
Pacific, //第一个未付值,默认为零
China=1860,
Japan,
US=1901,
Canada

}

--------------------------------------------------------------------------------

C#中的面向对象
析构函数:函数名与构造函数名一样,~函数名(),不接受参数,由垃圾回收器自动调用(GC.Collect()调用垃圾回收器)


virtual关键字:C#中,子类要重写父类的方法,必须把父类的方法标识为virtual(虚拟的),同时重写方法用override修饰
new 关键字:new关键字:在子类中定义的一个和父类方法签名一样,但是个全新的方法。并非重写父类的方法。
base关键字:用base关键字调用父类的方法

访问修饰符:
public 公有的,
internal 在一个项目中的,
protected有父子关系的类,
private仅所属类的成员

注意:如果有一个类既继承类又实现接口,类名要写在接口名前面。



--------------------------------------------------------------------------------

属性,索引器,委托,事件

属性:访问修饰一般为public,首字母大写。属性内有get和set访问器,get内必须要有return,set内有value关键字,代表从外部接受的值。
索引器:索引器的作用:像处理数组一样去处理类的对象。
public class Student
{
private string []obj=new string[10];

//this关键字在这里代表每一个类的对象,[]中整数是指通过下标访问
public string this[int index] //此是可以通过索引号去访问每一个类的成员
{
get
{
return obj[index];
}
set
{
if(value!=null)
obj[index]=value;
}
}
static void Main(string []args)
{
Student stucollection=new Student();
stucollection[0]="柯南";
stucollection[1]="小五郎";
stucollection[5]="怪盗基德";
}
}


委托:相当于函数指针,可使程序在运行是再指定具体要运行的方法。
(1) 定义委托:Public delegate int Call()
(2) 实例化委托:objcall=new Call(方法名)
(3) 调用委托:objcall();

事件:事件实际上是一种特殊的委托,委托每次只能指向一个方法,而事件可以指向多个方法
(1)定义一个委托public delegate void delegateMe();
(2)定义一个事件 private event delegate eventMe;
(3)订阅事件 eventMe+=new delegateMe(方法名1());
eventMe+=new delegateMe(方法名2());
(4) 引发事件 if(condition) then eventMe();



--------------------------------------------------------------------------------
多线程

创建线程实例:
Thread obj=new Thread(new ThreadStart(方法名称))
开始:Start();
休眠:Sleep();
终止:Abort();
挂起:Suspend();
恢复:Resume();
当前线程:Thread.CurrentThread
ThreadPriority枚举值用来指定调度线程的优先级(共5级)

lock关键字
C#中通过lock关键字提供同步
线程同步:确保不同的线程对共享资源进行访问时,每次只有一个线程访问资源。
Lock(this)
{
For(int i=0;i<10;i++)
{
//语句;
}
}



--------------------------------------------------------------------------------

数组集合对象

Array: Array和数组很相似,还可以相互转化和拷贝,很多方法都是是通用, 可以用Array的静态方法对数组实现反转,排序,这是数组本身无法做到的

using system.Array;
Array ar=Array.CreateInstance(typeof(int),5); //创建一个Array的实例
ar.SetValue(12,0); //赋值

Array.Reverse(ar); // 反转
Array.Sort(ar); // 排序

ArrayList:最常用的集合之一.集合的好处是在不知道数据大小时,可以实现容量自动增长,而数组做不到.
Add()添加元素
Remove(位置)移除元素

ArrayList al=new ArrayList();
//如果要遍历集合元素,
//方法一:
//将集合中的数拷贝到数组中
object []temp=al.ToArray();
foreach(object t in temp)
{
Console.WriteLine(t);
}

//方法二,使用迭代器
IEnumerator ie=al.GetEnumerator();
while(ie.MoveNext())
{
Console.WriteLine(ie.Current);
}

HashTable:以键值对的形式保存值

Hashtable hash=new Hashtable(4);
hash.Add("中国",1860);
hash.Add("德国",1940);

Console.WriteLine(hash["中国"].ToString());通过key获得value


SortedList :是 Hashtable 和 Array 的混合
能存放键值对,类似Hashtable
能通过自身提供的方法通过索引直接遍历,类似于Array
objsortlist.GetKey(i) 方法获得键
objsortlist.GetByIndex(i)方法获得值

.NET 2.0下读取数据库中的全部表以及表内的字段名

TDBOperator db = null;

try

{

db = TDBOperatorFactory.GetDBOperator(comFunction.getDBLink());

//打开数据库连接

db.Open();

System.Data.Common.DbConnection dc = db.getDbConnection();

string[] res = new string[4];

res[1] = "dbo";

//取得全部表名

DataTable dt = dc.GetSchema("Tables");

this.Text = dt.Rows.Count.ToString();

dt.WriteXml("table.xml");

foreach (System.Data.DataRow row in dt.Rows)

{

//取出数据库中系统表外的所有表名

if (row[3].ToString() == "TABLE")

{

listBox1.Items.Add(row[2].ToString());

listBox1.Items.Add("============================");

for (int i = 0; i < 4; i++) res[i] = null;

res[2] = row[2].ToString();

//取得相应表的所有字段

DataTable dtColumns = dc.GetSchema("Columns", res);

foreach (System.Data.DataRow rowColumns in dtColumns.Rows)

{

listBox1.Items.Add(rowColumns[3].ToString());

}

dtColumns.WriteXml(row[2].ToString() + "b.xml");

listBox1.Items.Add("============================");

}

}

}

catch (Exception ex)

{

comMsgBox.showError(ex.Message);

}

finally

{

db.Close();

}

C#通过ADO.NET建表点实现方法

新建表:
create table [表名]
(
[自动编号字段] int IDENTITY (1,1) PRIMARY KEY ,
[字段1] nVarChar(50) default '默认值' null ,
[字段2] ntext null ,
[字段3] datetime,
[字段4] money null ,
[字段5] int default 0,
[字段6] Decimal (12,4) default 0,
[字段7] image null ,
)

删除表:
Drop table [表名]

插入数据:
INSERT INTO [表名] (字段1,字段2) VALUES (100,'abc.NET')

删除数据:
DELETE FROM [表名] WHERE [字段名]>100

更新数据:
UPDATE [表名] SET [字段1] = 200,[字段2] = 'abc.NET' WHERE [字段三] = 'HAIWA'

新增字段:
ALTER TABLE [表名] ADD [字段名] NVARCHAR (50) NULL

删除字段:
ALTER TABLE [表名] DROP COLUMN [字段名]

修改字段:
ALTER TABLE [表名] ALTER COLUMN [字段名] NVARCHAR (50) NULL

重命名表:(Access 重命名表,请参考文章:在Access数据库中重命名表)
sp_rename '表名', '新表名', 'OBJECT'

新建约束:
ALTER TABLE [表名] ADD CONSTRAINT 约束名 CHECK ([约束字段] <= '2000-1-1')

删除约束:
ALTER TABLE [表名] DROP CONSTRAINT 约束名

新建默认值
ALTER TABLE [表名] ADD CONSTRAINT 默认值名 DEFAULT 'abc.NET' FOR [字段名]

删除默认值
ALTER TABLE [表名] DROP CONSTRAINT 默认值名

汉字转换为拼音的函数收藏

using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;

namespace SplitWord
{
/**//**//**//// 用C#实现汉字转化为拼音
/// 实现的原理就是先将汉字转化成为内码,然后通过内码和拼音的对照来查找。
public class chs2py
{
/**//**//**//**/
/**//**//**//**/
/**//**//**//**/
/**//**//**////
///将汉字转换成为拼音
///作者:
///完成于:
///

static Regex MyRegex = new Regex("^[一-龥]$"); //汉字的正则表达式.eg: if(MyRegex.IsMatch(chrstr.ToString()))
private static int[] pyvalue = new int[]{-20319,-20317,-20304,-20295,-20292,-20283,-20265,-20257,-20242,-20230,-20051,-20036,-20032,-20026,
-20002,-19990,-19986,-19982,-19976,-19805,-19784,-19775,-19774,-19763,-19756,-19751,-19746,-19741,-19739,-19728,
-19725,-19715,-19540,-19531,-19525,-19515,-19500,-19484,-19479,-19467,-19289,-19288,-19281,-19275,-19270,-19263,
-19261,-19249,-19243,-19242,-19238,-19235,-19227,-19224,-19218,-19212,-19038,-19023,-19018,-19006,-19003,-18996,
-18977,-18961,-18952,-18783,-18774,-18773,-18763,-18756,-18741,-18735,-18731,-18722,-18710,-18697,-18696,-18526,
-18518,-18501,-18490,-18478,-18463,-18448,-18447,-18446,-18239,-18237,-18231,-18220,-18211,-18201,-18184,-18183,
-18181,-18012,-17997,-17988,-17970,-17964,-17961,-17950,-17947,-17931,-17928,-17922,-17759,-17752,-17733,-17730,
-17721,-17703,-17701,-17697,-17692,-17683,-17676,-17496,-17487,-17482,-17468,-17454,-17433,-17427,-17417,-17202,
-17185,-16983,-16970,-16942,-16915,-16733,-16708,-16706,-16689,-16664,-16657,-16647,-16474,-16470,-16465,-16459,
-16452,-16448,-16433,-16429,-16427,-16423,-16419,-16412,-16407,-16403,-16401,-16393,-16220,-16216,-16212,-16205,
-16202,-16187,-16180,-16171,-16169,-16158,-16155,-15959,-15958,-15944,-15933,-15920,-15915,-15903,-15889,-15878,
-15707,-15701,-15681,-15667,-15661,-15659,-15652,-15640,-15631,-15625,-15454,-15448,-15436,-15435,-15419,-15416,
-15408,-15394,-15385,-15377,-15375,-15369,-15363,-15362,-15183,-15180,-15165,-15158,-15153,-15150,-15149,-15144,
-15143,-15141,-15140,-15139,-15128,-15121,-15119,-15117,-15110,-15109,-14941,-14937,-14933,-14930,-14929,-14928,
-14926,-14922,-14921,-14914,-14908,-14902,-14894,-14889,-14882,-14873,-14871,-14857,-14678,-14674,-14670,-14668,
-14663,-14654,-14645,-14630,-14594,-14429,-14407,-14399,-14384,-14379,-14368,-14355,-14353,-14345,-14170,-14159,
-14151,-14149,-14145,-14140,-14137,-14135,-14125,-14123,-14122,-14112,-14109,-14099,-14097,-14094,-14092,-14090,
-14087,-14083,-13917,-13914,-13910,-13907,-13906,-13905,-13896,-13894,-13878,-13870,-13859,-13847,-13831,-13658,
-13611,-13601,-13406,-13404,-13400,-13398,-13395,-13391,-13387,-13383,-13367,-13359,-13356,-13343,-13340,-13329,
-13326,-13318,-13147,-13138,-13120,-13107,-13096,-13095,-13091,-13076,-13068,-13063,-13060,-12888,-12875,-12871,
-12860,-12858,-12852,-12849,-12838,-12831,-12829,-12812,-12802,-12607,-12597,-12594,-12585,-12556,-12359,-12346,
-12320,-12300,-12120,-12099,-12089,-12074,-12067,-12058,-12039,-11867,-11861,-11847,-11831,-11798,-11781,-11604,
-11589,-11536,-11358,-11340,-11339,-11324,-11303,-11097,-11077,-11067,-11055,-11052,-11045,-11041,-11038,-11024,
-11020,-11019,-11018,-11014,-10838,-10832,-10815,-10800,-10790,-10780,-10764,-10587,-10544,-10533,-10519,-10331,
-10329,-10328,-10322,-10315,-10309,-10307,-10296,-10281,-10274,-10270,-10262,-10260,-10256,-10254};
private static string[] pystr = new string[]{"a","ai","an","ang","ao","ba","bai","ban","bang","bao","bei","ben","beng","bi","bian","biao",
"bie","bin","bing","bo","bu","ca","cai","can","cang","cao","ce","ceng","cha","chai","chan","chang","chao","che","chen",
"cheng","chi","chong","chou","chu","chuai","chuan","chuang","chui","chun","chuo","ci","cong","cou","cu","cuan","cui",
"cun","cuo","da","dai","dan","dang","dao","de","deng","di","dian","diao","die","ding","diu","dong","dou","du","duan",
"dui","dun","duo","e","en","er","fa","fan","fang","fei","fen","feng","fo","fou","fu","ga","gai","gan","gang","gao",
"ge","gei","gen","geng","gong","gou","gu","gua","guai","guan","guang","gui","gun","guo","ha","hai","han","hang",
"hao","he","hei","hen","heng","hong","hou","hu","hua","huai","huan","huang","hui","hun","huo","ji","jia","jian",
"jiang","jiao","jie","jin","jing","jiong","jiu","ju","juan","jue","jun","ka","kai","kan","kang","kao","ke","ken",
"keng","kong","kou","ku","kua","kuai","kuan","kuang","kui","kun","kuo","la","lai","lan","lang","lao","le","lei",
"leng","li","lia","lian","liang","liao","lie","lin","ling","liu","long","lou","lu","lv","luan","lue","lun","luo",
"ma","mai","man","mang","mao","me","mei","men","meng","mi","mian","miao","mie","min","ming","miu","mo","mou","mu",
"na","nai","nan","nang","nao","ne","nei","nen","neng","ni","nian","niang","niao","nie","nin","ning","niu","nong",
"nu","nv","nuan","nue","nuo","o","ou","pa","pai","pan","pang","pao","pei","pen","peng","pi","pian","piao","pie",
"pin","ping","po","pu","qi","qia","qian","qiang","qiao","qie","qin","qing","qiong","qiu","qu","quan","que","qun",
"ran","rang","rao","re","ren","reng","ri","rong","rou","ru","ruan","rui","run","ruo","sa","sai","san","sang",
"sao","se","sen","seng","sha","shai","shan","shang","shao","she","shen","sheng","shi","shou","shu","shua",
"shuai","shuan","shuang","shui","shun","shuo","si","song","sou","su","suan","sui","sun","suo","ta","tai",
"tan","tang","tao","te","teng","ti","tian","tiao","tie","ting","tong","tou","tu","tuan","tui","tun","tuo",
"wa","wai","wan","wang","wei","wen","weng","wo","wu","xi","xia","xian","xiang","xiao","xie","xin","xing",
"xiong","xiu","xu","xuan","xue","xun","ya","yan","yang","yao","ye","yi","yin","ying","yo","yong","you",
"yu","yuan","yue","yun","za","zai","zan","zang","zao","ze","zei","zen","zeng","zha","zhai","zhan","zhang",
"zhao","zhe","zhen","zheng","zhi","zhong","zhou","zhu","zhua","zhuai","zhuan","zhuang","zhui","zhun","zhuo",
"zi","zong","zou","zu","zuan","zui","zun","zuo"};
/**//**//**////
/// 转化汉字的全部拼音
///

///
///
public static string Convert(string chrstr)
{
Regex MyRegex = new Regex("^[一-龥]$");
byte[] array = new byte[2];
string returnstr = "";
int chrasc = 0;
int i1 = 0;
int i2 = 0;
char[] nowchar = chrstr.ToCharArray();
for (int j = 0; j < nowchar.Length; j++)
{
if (MyRegex.IsMatch(nowchar[j].ToString()))
{
array = System.Text.Encoding.Default.GetBytes(nowchar[j].ToString());
i1 = (short)(array[0]);
i2 = (short)(array[1]);
chrasc = i1 * 256 + i2 - 65536;
if (chrasc > 0 && chrasc < 160)
{
returnstr += nowchar[j];
}
else
{
for (int i = (pyvalue.Length - 1); i >= 0; i--)
{
if (pyvalue[i] <= chrasc)
{
returnstr += pystr[i];
break;
}
}
}
}
else
{
returnstr += nowchar[j].ToString();
}
}
return returnstr;
}
//ChineseToPY
/**//**//**////
/// 只转换汉字首字母
///

///
///
public static string GetChineseSpell(string strText)
{
int len = strText.Length;
string myStr = "";
for (int i = 0; i < len; i++)
{
myStr += getSpell(strText.Substring(i, 1));
}
return myStr;
}


public static string getSpell(string cnChar)
{
byte[] arrCN = Encoding.Default.GetBytes(cnChar);
if (arrCN.Length > 1)
{
int area = (short)arrCN[0];
int pos = (short)arrCN[1];
int code = (area << 8) + pos;
int[] areacode ={ 45217, 45253, 45761, 46318, 46826, 47010, 47297, 47614, 48119, 48119, 49062, 49324, 49896, 50371, 50614, 50622, 50906, 51387, 51446, 52218, 52698, 52698, 52698, 52980, 53689, 54481 };
for (int i = 0; i < 26; i++)
{
int max = 55290;
if (i != 25) max = areacode[i + 1];
if (areacode[i] <= code && code < max)
{
return Encoding.Default.GetString(new byte[]{ (byte)(65 + i) });
}
}
return "*";
}
else return cnChar;
}
}
}

关于.NET使用自定义XML做参数配置文件

WEB开发,尤其是大型项目的开发,其中不乏大名鼎鼎的CMS,XXMS,呵呵.
他们都有个共同的特点,那就是网站配置参数N多.
怎么设置好众多的参数配置,是在项目初期需要规划的一个重点.
总结这几年做WEB开发的一点点积累.个人认为以下方案是比较合理化的,对于以后参数的增加修改带来的一些问题可以得到一定的控制.同样适合WINFORM哈.

运行环境: .NET 2.0
在项目设计过程中,采用模块化设计,所以参数也得独立开,每个模块的参数配置单独存放与一个单独的XML文件中.
原理:利用XML的序列化与反序列化配合实体读取和保存参数设置到XML文件中.
先看XML结构
SystemInfo.xml



网站标题
SiteTitle
设置网站的标题
Text
博客园
^.*$
False


网站地址
SiteUrl
设置网站的地址
Text
http://www.cnblogs.com
^.*$
False


配置文件子节点结构
/**/'''
''' 配置文件结构
'''

'''

_
Public Class ItemClass Item

Private _ColsDisplay As UInt16
Private _isRequired As Boolean
Private _name As String
Private _title As String
Private _explain As String
Private _mode As String
Private _value As String
Private _pattern As String
Private _range As String
Private _rangeHint As String

/**/'''
''' 节点名称
'''

Public Property Name()Property Name() As String
Get
Return Me._name
End Get
Set(ByVal value As String)
Me._name = value
End Set
End Property

/**/'''
''' 节点标题
'''

Public Property Title()Property Title() As String
Get
Return Me._title
End Get
Set(ByVal value As String)
Me._title = value
End Set
End Property

/**/'''
''' 节点说明
'''

Public Property Explain()Property Explain() As String
Get
Return Me._explain
End Get
Set(ByVal value As String)
Me._explain = value
End Set
End Property

/**/'''
''' 节点值类型
'''

Public Property Mode()Property Mode() As String
Get
Return Me._mode
End Get
Set(ByVal value As String)
Me._mode = value
End Set
End Property

/**/'''
''' 节点值
'''

Public Property Value()Property Value() As String
Get
Return Me._value
End Get
Set(ByVal value As String)
Me._value = value
End Set
End Property

/**/'''
''' 限制格式
'''

Public Property Pattern()Property Pattern() As String
Get
Return Me._pattern
End Get
Set(ByVal value As String)
Me._pattern = value
End Set
End Property

/**/'''
''' 选择范围
'''

Public Property Range()Property Range() As String
Get
Return Me._range
End Get
Set(ByVal value As String)
Me._range = value
End Set
End Property

/**/'''
''' 选择范围标题
'''

Public Property RangeHint()Property RangeHint() As String
Get
Return Me._rangeHint
End Get
Set(ByVal value As String)
Me._rangeHint = value
End Set
End Property

/**/'''
''' 是否必需
'''

Public Property IsRequired()Property IsRequired() As Boolean
Get
Return Me._isRequired
End Get
Set(ByVal value As Boolean)
Me._isRequired = value
End Set
End Property

/**/'''
''' 列显示
'''

Public Property ColsDisplay()Property ColsDisplay() As UInt16
Get
Return Me._ColsDisplay
End Get
Set(ByVal value As UInt16)
Me._ColsDisplay = value
End Set
End Property

End Class
自定义配置文件实体
/**/'''
''' 自定义配置文件实体
'''

'''

_
Public Class ConfigsClass Configs

Private _SiteTitle As Item
Private _SiteUrl As Item

/**/'''
''' 网站标题
'''

Public Property SiteTitle()Property SiteTitle() As Item
Get
Return Me._SiteTitle
End Get
Set(ByVal value As Item)
Me._SiteTitle = value
End Set
End Property

/**/'''
''' 网站地址
'''

Public Property SiteUrl()Property SiteUrl() As Item
Get
Return Me._SiteUrl
End Get
Set(ByVal value As Item)
Me._SiteUrl = value
End Set
End Property

End Class
以下需引用
Imports System.Xml
Imports System.Xml.Serialization

序列化XML文件的读取
/**/'''
''' 读取序列化XML配置文件内容
'''

''' 类型
''' 配置文件地址,绝对地址
'''
'''
Public Shared Function Deserialize()Function Deserialize(ByVal Types As Type, ByVal FilePath As String) As Object
Dim Fs As FileStream = Nothing
Dim Xmls As Object = String.Empty
Fs = New FileStream(FilePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)
Dim Xms As XmlSerializer = New XmlSerializer(Types)
Xmls = Xms.Deserialize(Fs)
Fs.Flush()
Fs.Close()
Return Xmls
End Function
XML文件保存
/**/'''
''' 保存序列化XML配置文件内容
'''

''' 类型
''' 实体
''' 配置文件地址,绝对地址
'''
Public Shared Sub SaveConfig()Sub SaveConfig(ByVal Types As Type, ByVal Info As Configs, ByVal FilePath As String)
Dim Fs As Stream = New FileStream(FilePath, FileMode.Create, FileAccess.Write, FileShare.ReadWrite)
Dim Xms As XmlSerializer = New XmlSerializer(Types)
Xms.Serialize(Fs, Info)
Fs.Flush()
Fs.Close()
End Sub
调用参数

Dim Info As Configs = New Configs
Info = Deserialize(GetType (Configs), "SystemInfo.Xml")
Response.write(Info.SiteTitle.Title)
Response.write(Info.SiteTitle.Value)

以上为全部代码

下面做简单说明
以前自己做项目的时候.只是运用到简单的序列化与反序列化,同样也是在CNBLOG先辈们的手迹中得到的解释.
在运用一段时间后发现很繁琐. 因为我只用到了一层结构.


博客园

虽然这样很简单明了.可是在实际开发中,不免存在一些问题,比如:
1、输入值的类型判断
2、输入值是否允许空
3、输入值是否符合指定类型
4、在做UI的时候还需要找到对应的控件,再写相关的说明文字。
等等。。很繁琐。

而新的代码。解决了这些问题,在使用中,只需要调用相应节点的值就OK了。在对于内容解释及类型控制上尤其方便。再也不需要因为更改一个参数的控制,而去在N个HTML代码中定位你的配置参数控件,然后再XXXXX。直接使用XML文件编辑器修改XML文件就OK啦。

小弟第一次发表,欢迎大家批评指正!

一种简便实效的配置文件读写方法

主要做法:

第一步,将配置信息做一个简单的类。

要点:因为要用到序列化,而且是用XmlSerializer来序列化,所以要存到文件的变量信息都要声明为Public,要序列化的类用修饰。

示例:一个连接数据库的配置信息

'配置信息

Public Class Item

'初始默认值

Public ID As Integer = 0

Public Server As String = "(Local)"

Public Database As String = "NorthWind"

Public Tusted As Boolean = True

Public User As String = ""

Public Password As String = ""

End Class

第二步:配置处理的类。

说明:这个类是通用的。用到别的配置,你只需修改上面的配置信息类就可以了。它实现了存档和读取的功能,并转化为配置信息对象,操作起来较为方便。你可以添加内容加密的处理。

Public Class Config

'默认ConnectionInfo的ID

Public ID As Integer

'必须是Public,XmlSerializer只对Pulbic变量作用

Public Items As Item()

Private m_Count As Integer = 0

'添加配置信息

Public Sub Add(ByVal ConnectionInfo As Item)

If ConnectionInfo Is Nothing Then Exit Sub

If m_Count > 0 Then

If Not Me.ConnectionInfo(ConnectionInfo.ID) Is Nothing Then

MsgBox(ID.ToString & "已存在")

Exit Sub

End If

End If

ReDim Preserve Me.Items(m_Count)

Me.Items(m_Count) = ConnectionInfo

m_Count += 1

End Sub

'取指定ID的配置信息

Public ReadOnly Property ConnectionInfo(ByVal ID As Integer) As Item

Get

Dim mItem As Item

Dim i As Integer

For i = 0 To m_Count - 1

If Me.Items(i).ID = ID Then

mItem = Me.Items(ID)

Exit For

End If

Next

Return mItem

End Get

End Property

'序列化并保存到指定文件

Public Sub SaveXmlFile(ByVal FileName As String)

If Me Is Nothing Then Exit Sub

Dim XmlWriter As New System.IO.StreamWriter(FileName, False)

XmlWriter.Write(SerializeClass.GetXML(Me))

XmlWriter.Close()

End Sub

'从指定文件读取反序列化转为对象

Public Function LoadXmlFile(ByVal FileName As String) As Config

Dim XmlReader As New System.IO.StreamReader(FileName, System.Text.Encoding.Default)

Dim mConfig As Config

mConfig = CType(SerializeClass.LoadXML(GetType(Config), XmlReader.ReadToEnd), Config)

XmlReader.Close()

mConfig.m_Count = mConfig.Items.Length

Return mConfig

End Function

End Class


就以上两步就可以了,下面这个类是用来序列化用的。

'这是用XmlSerializer序列化对象的类

Public Class SerializeClass

Public Shared Function GetXML(ByVal mObject As Object) As String

Dim oSerializer As New System.Xml.Serialization.XmlSerializer(mObject.GetType)

Dim oStringWriter As New System.IO.StringWriter

oSerializer.Serialize(oStringWriter, mObject)

Return oStringWriter.ToString

End Function

Public Shared Function LoadXML(ByVal mClass As Type, ByVal XML As String) As Object

Dim oSerializer As New System.Xml.Serialization.XmlSerializer(mClass)

Dim oStringReader As New System.IO.StringReader(XML)

Return oSerializer.Deserialize(oStringReader)

End Function

End Class


以下是使用方法示例:

'测试存配置文件

Private Sub TestSaveConfig()

Dim mConfig As Config = New Config

Dim mItem As Item

mItem = New Item

mConfig.Add(mItem)

mItem = New Item

With mItem

.ID = 1

.User = "Master"

.Password = "123456"

.Tusted = False

End With

mConfig.Add(mItem)

mConfig.SaveXmlFile(Application.StartupPath & "\Config.xml")

End Sub

'测试读配置文件

Private Sub TestLoadConfig()

Dim mConfig As Config = New Config

mConfig = mConfig.LoadXmlFile(Application.StartupPath & "\Config.xml")

'读取默认值的用户名

MsgBox(mConfig.Items(mConfig.ID).User)

'不妨修改一下配置

mConfig.ID = 1

mConfig.ConnectionInfo(0).Server = "Server"

mConfig.ConnectionInfo(1).Database = "Master"

'再存盘

mConfig.SaveXmlFile(Application.StartupPath & "\Config.xml")

End Sub