.NET知识

2010年12月17日

转载自http://www.cnblogs.com/yangjie5188/archive/2008/02/21/1076767.html

今天在浏览DevTopics的博客时,发现一篇介绍String的随笔,介绍的是判断一个String变量是否为空时,String的一个方法和一个属性之间的比较,给一个string变量 's', 下面那个表达式更快?

1. String.IsNullOrEmpty( s )
2. s == null || s.Length == 0

如果你猜第二个,那么你是对的.它将比String.IsNullOrEmpty方法快15%,但这种也是以百万分之一秒来衡量的!
这里有一个简单的例子来比较2种方式:

?
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
using System;
namespace StringNullEmpty
{
class Program
{
static void Main( string [] args )
{
long loop = 100000000;
string s = null ;
long option = 0;
long empties1 = 0;
long empties2 = 0;
DateTime time1 = DateTime.Now;
for ( long i = 0; i < loop; i++)
{
option = i % 4;
switch (option)
{
case 0:
s = null ;
break ;
case 1:
s = String.Empty;
break ;
case 2:
s = "H" ;
break ;
case 3:
s = "HI" ;
break ;
}
if (String.IsNullOrEmpty( s ))
empties1++;
}
DateTime time2 = DateTime.Now;
for ( long i = 0; i < loop; i++)
{
option = i % 4;
switch (option)
{
case 0:
s = null ;
break ;
case 1:
s = String.Empty;
break ;
case 2:
s = "H" ;
break ;
case 3:
s = "HI" ;
break ;
}
if (s == null || s.Length == 0)
empties2++;
}
DateTime time3 = DateTime.Now;
TimeSpan span1 = time2.Subtract( time1 );
TimeSpan span2 = time3.Subtract( time2 );
Console.WriteLine( "(String.IsNullOrEmpty( s )): Time={0} Empties={1}" ,
span1, empties1 );
Console.WriteLine( "(s == null || s.Length == 0): Time={0} Empties={1}" ,
span2, empties2 );
Console.ReadLine();
}
}
}

posted @ 2010-12-17 21:21 羽落无声 阅读(328) 评论(1)  编辑
ADO用了这么久,每次用向导创建ADO的数据库连接字符串时总会有产生一个Persist Security Info属性,平时没太注意,因为设置为True或False时对数据库连接没有任何影响。不过心理还是不爽,今天有时间查询了一下资料,总算搞清楚了它的作用。

Persist Security Info属性的意思是表示是否保存安全信息,其实可以简单的理解为"ADO在数据库连接成功后是否保存密码信息",

True表示保存,False表示不保存

ADO缺省为True
(ADO.net缺省为False,未测试,根据参考资料上说的)

具体可以通过ADO的Connect对象的ConnectString属性进行验证,如下所示(以下在Delphi7中测试通过):

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

数据库连接前

ConnectString="Provider=MSDAORA.1;Password=mypassword;User Source=ydgl22;Persist Security Info=false"

数据库连接成功后

ConnectString="Provider=MSDAORA.1;User Source=ydgl22"

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

数据库连接前

ConnectString="Provider=MSDAORA.1;Password=mypassword;User Source=ydgl22;Persist Security Info=true"

数据库连接成功后

ConnectString="Provider=MSDAORA.1;Password=mypassword;User Source=ydgl22"

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

总体来说,如果数据库连接成功后不再需要连接的密码,出于安全性考虑,还是建议将Persist Security Info设为false,以防止后门程序取得数据库连接的密码(windows2003在sp1前就发生过这个问题)。
posted @ 2010-12-17 21:21 羽落无声 阅读(46) 评论(0)  编辑

C# treeview递归操作数据库主要是想大家展示通过C# treeview递归来实现数据库的树形结构的呈现,希望对你了解C# treeview递归有所比帮助。

C# treeview递归操作数据库需要注意什么呢?C# treeview递归操作数据库的具体步骤是什么呢?这里我们通过具体的实现步骤来向你详细介绍相应的内容。

C# treeview递归1、建立数据库:

f_id 项目ID号 ,f_front 父ID号 ,f_name名称,f_type类型,f_layer所处层,f_order同层的顺序号;(f_layer,f_order不要也可,这里我主要是需要同层排序才用到)

C# treeview递归2、数据库的操作

然后“select f_id,f_front,f_name,f_type from data”取得DataSet数据集dsFrame;treeview 名称设为tvDept

C# treeview递归3、写函数 构建treeveiw树形:

public void AddTree(int ParentID, TreeNode pNode)
{ DataView dvTree = new DataView(dtTree);
//就是dtTree = dsFrame.Tables[0];
string Fstr = "[f_front] = " + ParentID; dvTree.RowFilter = Fstr;
foreach(DataRowView Row in dvTree)
{ TreeNode Node = new TreeNode();
if (pNode == null) //处理主节点
{ Node.Name = Row["f_id"].ToString();
//这里+了2个值分别到Name和Text,可随便
Node.Text = Row["f_name"].ToString();
if (Row["f_type"].ToString() == "岗位")
//这个不要也可以,主要为了不同类型显示不同图标 { Node.ImageIndex = 1; Node.SelectedImageIndex=1; }
else 
{ Node.ImageIndex = 0; Node.SelectedImageIndex=0; }
tvDept.Nodes.Add(Node);
//加入 AddTree(Int32.Parse(Row["f_id"].ToString()), Node); //递归
} else //处理子节点
{ Node.Name = Row["f_id"].ToString(); Node.Text = Row["f_name"].ToString();
if (Row["f_type"].ToString() == "岗位")
{ Node.ImageIndex = 1; Node.SelectedImageIndex = 1; }
else { Node.ImageIndex = 0; Node.SelectedImageIndex=0; }
pNode.Nodes.Add(Node);
AddTree(Int32.Parse(Row["f_id"].ToString()), Node); }
}
}

C# treeview递归4、调用实现

调用方法 AddTree(0, (TreeNode)null); //0就是处于最高级其f_front=0,数据库里1为顶层那就是1,这个随便 最好+一句 tvDept.ExpandAll();展开所有项。

C# treeview递归的数据库操作我们就向你介绍到这里,希望对你了解和学习C# treeview递归有所帮助。

posted @ 2010-12-17 21:21 羽落无声 阅读(149) 评论(0)  编辑
posted @ 2010-12-17 21:21 羽落无声 阅读(44) 评论(0)  编辑

发现网上关于ListView的视频教程大多没讲Details用法,找了许久

发现还是msdn讲的最好

private void InitializeListView()
{
this.ListView1 = new System.Windows.Forms.ListView();

// Set properties such as BackColor and DockStyle and Location.
this.ListView1.BackColor = System.Drawing.SystemColors.Control;
this.ListView1.Dock = System.Windows.Forms.DockStyle.Top;
this.ListView1.Location = new System.Drawing.Point(0, 0);
this.ListView1.Size = new System.Drawing.Size(292, 130);
this.ListView1.View = System.Windows.Forms.View.Details;
this.ListView1.HideSelection = false;

// Allow the user to select multiple items.
this.ListView1.MultiSelect = true;

// Show CheckBoxes in the ListView.
this.ListView1.CheckBoxes = true;

//Set the column headers and populate the columns.
ListView1.HeaderStyle = ColumnHeaderStyle.Nonclickable;

ColumnHeader columnHeader1 = new ColumnHeader();
columnHeader1.Text = "Breakfast Choices";
columnHeader1.TextAlign = HorizontalAlignment.Left;
columnHeader1.Width = 146;

ColumnHeader columnHeader2 = new ColumnHeader();
columnHeader2.Text = "Price Each";
columnHeader2.TextAlign = HorizontalAlignment.Center;
columnHeader2.Width = 142;

this.ListView1.Columns.Add(columnHeader1);
this.ListView1.Columns.Add(columnHeader2);

string[] foodList = new string[]{"Juice", "Coffee",
"Cereal & Milk", "Fruit Plate", "Toast& Jelly",
"Bagel & Cream Cheese"};

string[] foodPrice = new string[]{"1.09", "1.09", "2.19",
"2.79", "2.09", "2.69"};

int count;

// Members are added one at a time, so call BeginUpdate to ensure
// the list is painted only once, rather than as each list item is added.
ListView1.BeginUpdate();

for(count = 0; count < foodList.Length; count++)
{
ListViewItem listItem = new ListViewItem(foodList[count]);
listItem.SubItems.Add(foodPrice[count]);
ListView1.Items.Add(listItem);
}

//Call EndUpdate when you finish adding items to the ListView.
ListView1.EndUpdate();
this.Controls.Add(this.ListView1);
}

posted @ 2010-12-17 21:21 羽落无声 阅读(340) 评论(0)  编辑

转载自http://www.cnblogs.com/Charles2008/archive/2010/03/15/1686450.html


最近在做winform的程序中,需要只能打开一个程序,如果已经存在,则激活该程序的窗口,并显示在最前端。在网上google了一哈,找到了很多的解决方案。这里我整理了3种方案,并经过了测试,现和朋友们分享:

一、使用用互斥量(System.Threading.Mutex)

同步基元,它只向一个线程授予对共享资源的独占访问权。在程序启动时候,请求一个互斥体,如果能获取对指定互斥的访问权,就职运行一个实例。
代码
bool createNew;
using (System.Threading.Mutex mutex = new System.Threading.Mutex(true, Application.ProductName, out createNew))
{
if (createNew)
{
Application.Run(new Form1());
}
else
{
MessageBox.Show("应用程序已经在运行中...")
System.Threading.Thread.Sleep(1000);
System.Environment.Exit(1);
}
}





二、使用进程名


代码
Process[] processes = System.Diagnostics.Process.GetProcessesByName(Application.CompanyName);
if (processes.Length > 1)
{
MessageBox.Show("应用程序已经在运行中。。");
Thread.Sleep(1000);
System.Environment.Exit(1);
}
else
{
Application.Run(new Form1());
}





三、调用Win32 API,并激活并程序的窗口,显示在最前端


代码
/// 该函数设置由不同线程产生的窗口的显示状态
/// </summary>
/// <param name="hWnd">窗口句柄</param>
/// <param name="cmdShow">指定窗口如何显示。查看允许值列表,请查阅ShowWlndow函数的说明部分</param>
///< returns>如果函数原来可见,返回值为非零;如果函数原来被隐藏,返回值为零</returns>
[DllImport("User32.dll")]
private static extern bool ShowWindowAsync(IntPtr hWnd, int cmdShow);
/// <summary>
/// 该函数将创建指定窗口的线程设置到前台,并且激活该窗口。键盘输入转向该窗口,并为用户改各种可视的记号。
/// 系统给创建前台窗口的线程分配的权限稍高于其他线程。
/// </summary>
/// <param name="hWnd">将被激活并被调入前台的窗口句柄</param>
///< returns>如果窗口设入了前台,返回值为非零;如果窗口未被设入前台,返回值为零</returns>
[DllImport("User32.dll")]
private static extern bool SetForegroundWindow(IntPtr hWnd);




代码
private const int SW_SHOWNOMAL = 1;
private static void HandleRunningInstance(Process instance)
{
ShowWindowAsync(instance.MainWindowHandle, SW_SHOWNOMAL);//显示
SetForegroundWindow(instance.MainWindowHandle);//当到最前端
}
private static Process RuningInstance()
{
Process currentProcess = Process.GetCurrentProcess();
Process[] Processes = Process.GetProcessesByName(currentProcess.ProcessName);
foreach (Process process in Processes)
{
if (process.Id != currentProcess.Id)
{
if (Assembly.GetExecutingAssembly().Location.Replace("/", "\\") == currentProcess.MainModule.FileName)
{
return process;
}
}
}
return null;
}


代码
Process process = RuningInstance();
if (process == null)
{
Application.Run(new Form1());
}
else
{
MessageBox.Show("应用程序已经在运行中。。。");
HandleRunningInstance(process);
//System.Threading.Thread.Sleep(1000);
//System.Environment.Exit(1);
}



这里整理了三种方案,希望朋友们提出更多的解决方案。谢谢!

Best Regards,

Charles Chen

posted @ 2010-12-17 21:21 羽落无声 阅读(185) 评论(0)  编辑

转载自http://blog.csdn.net/jin20000/archive/2008/10/24/3136791.aspx

互斥进程(程序), 简单点说,就是在系统中只能有该程序的一个实例运行. 现在很多软件都有这功能,如Maxthon可以设置为"只允 许打开一个窗体",还有Bitcomet等. 我也是看到这些软件的这个功能才来研究这个问题的.要实现程序的互斥,通常有三中方式,下面 用 C# 语言来实现:


实现方式一: 使用线程互斥变量. 通过定义互斥变量来判断是否已运行实例.C#实现如下:

把program.cs文件里的Main()函数改为如下代码:

static void Main()
{
bool runone;
System.Threading.Mutex run = new System.Threading.Mutex(true, "xinbiao_a_test", out runone);
if (runone)
{
run.ReleaseMutex();
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
else
{
MessageBox.Show("已经运行了一个实例了。");
}
}

说明:程序中通过语 句 System.Threading.Mutex run = new System.Threading.Mutex(true, "xinbiao_a_test", out runone);来申明一个互斥体变量run,其中"xinbiao_a_test"为互斥体名,布尔变量runone用来保存是否已经运行了该程序事例.

实现方式二:采用判断进程的方式,我们在运行程序前,查找进程中是否有同名的进程,同时运行位置也相同程,如是没有运行该程序,如果有就就不运行.在C#中应用System.Diagnostics名字空间中的Process类来实现,主要代码如下:

1,在program.cs文件中添加函数如下:

public static System.Diagnostics.Process RunningInstance()
{
System.Diagnostics.Process current = System.Diagnostics.Process.GetCurrentProcess();
System.Diagnostics.Process[] processes = System.Diagnostics.Process.GetProcesses();
foreach (System.Diagnostics.Process process in processes) //查找相同名称的进程
{
if (process.Id != current.Id) //忽略当前进程
{ //确认相同进程的程序运行位置是否一样.
if (System.Reflection.Assembly.GetExecutingAssembly().Location.Replace("/", @"\") == current.MainModule.FileName)
{ //Return the other process instance.
return process;
}
}
} //No other instance was found, return null.
return null;
}

2,把Main ()函数改为如下代码:

static void Main()
{
if(RunningInstance()==null)
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
else
{
MessageBox.Show("已经运行了一个实例了。");
}
}

实现方式三:全局原子法,创建程序前,先检查全局原子表中看是否存在特定原子A(创建时添加的),存在时停止创建,说明该程序已运行了一个实例;不存在则运行程序并想全局原子表中添加特定原子A;退出程序时要记得释放特定的原子A哦,不然要到关机才会释放。C#实现如下:

1、申明WinAPI函数接口:

[System.Runtime.InteropServices.DllImport("kernel32.dll")]

public static extern UInt32 GlobalAddAtom(String lpString); //添加原子

[System.Runtime.InteropServices.DllImport("kernel32.dll")]

public static extern UInt32 GlobalFindAtom(String lpString); //查找原子

[System.Runtime.InteropServices.DllImport("kernel32.dll")]

public static extern UInt32 GlobalDeleteAtom(UInt32 nAtom); //删除原子

2、修改Main()函数如下:

static void Main()
{
if (GlobalFindAtom("xinbiao_test") == 77856768) //没找到原子"xinbiao_test"
{
GlobalAddAtom("xinbiao_test"); //添加原子"xinbiao_test"
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
else
{
MessageBox.Show("已经运行了一个实例了。");
}
}


3、在FormClosed事件中添加如下代码:

GlobalDeleteAtom(GlobalFindAtom("xinbiao_test"));//删除原子"xinbiao_test"

以上为创建互斥程序(进程)的基本通用的思想,个人认为,第一种方法最好。以上所有代码都在VS.NET2005 中测试通过。
posted @ 2010-12-17 21:21 羽落无声 阅读(95) 评论(0)  编辑

写的真的很好……学习了,也希望更多人能看到

http://www.cnblogs.com/sifang2004/archive/2006/07/14/450565.html


谈谈C#中的接口
接口的相关陈述

1.一个接口定义了一个契约。

2.接口可以包容方法、C#属性、事件、以及索引器。

3.在一个接口声明中,我们可以声明零个或者多个成员。

4.所有接口成员的默认访问类型都是public。

5.如果在接口成员声明中包括了任何修饰符,那么会产生一个编译器错误。

6.与一个非抽象类类似,一个抽象类必须提供接口中所有成员的实现,只要这些成员在这个类的基类中出现过。


接口的理解

1.面向接口编程利用OO的一个基本性质——多态,相同方法不同表现。可以这样想一下,client编写自己程序的时候,如果直接面向一个具体类写程序,那这个程序有个风吹草动的,那client就要受到影响,但如果面向一个接口就不同了,某个具体类变了,只知接口,不知具体类的client就可以完全不动。 都说上层领导比较好当,因为可以干的事通常对老百姓来说是虚的,越虚就越不容易错。
这个道理在OO中也是适用的。

2. 换个视角看,面向接口编程反映OO的另一个方面——封装,接口将具体实现封装了起来,可以不影响客户的情况下切换实现

3. 接口的作用,一言以蔽之,就是标志类的类别(type of class)。把不同类型的类归于不同的接口,可以更好的管理他们。OO的精髓,我以为,是对对象的抽象,最能体现这一点的就是接口。为什么我们讨论设计模式都只针对具备了抽象能力的语言(比如c++、java、c#等),就是因为设计模式所研究的,实际上就是如何合理的去抽象。(cowboy的名言是“抽象就是抽去像的部分”,看似调侃,实乃至理)。



空接口的使用
在接口使用的时候,空接口有2种情况:
1.类似于ObjectBuilder中的IBuilderPolicy,他们往往是做一个标记,表示需要某个功能.当然你也可以这么用,来表示你的类具有某个功能,实现了你的某个接口.

namespace Microsoft.Practices.ObjectBuilder

{

/// <summary>

/// Represents a builder policy interface. Since there are no fixed requirements

/// for policies, it acts as a marker interface from which to derive all other

/// policy interfaces.

/// </summary>

public interface IBuilderPolicy

{

}

}



2.你的接口继承了别的接口(非空),你的接口本身没有声明函数.这种情况一般是你不希望用户使用父接口作为参数类型,因为他们的用途可能不同,此时就可以用空接口来实现.



interface Text

{

string getText();

}



interface SqlText : Text

{



}

可以看到,Text接口是用于返回一个字符串.而SqlText是一个空接口,它继承了Text接口.也就是说SqlText也是一种Text.但是我们可以知道,任何一个字符串不一定是Sql字符串,所以此时声明了一个SqlText接口来用于表名当前的字符串是一个Sql字符串.你的函数可以这样声明:

public void doQuery(SqlText sqlText)

而不是这样:

public void doQuery(Text text)

避免用户产生歧义的想法,一眼看去,就明白应该传入一个Sql字符串.
接口的成员为什么没有委托

我们都知道C#的接口是可以包含事件的,其实当我们看到事件的时候,很容易就会想到委托,委托是事件的基础,如果对委托和事件不是特别清楚的程序员就一定不会明白,为什么C#接口中可以包含事件而不能有委托呢。其实简单的说法就是委托也是类型,delegate关键字引入的是一个新的类型,所以一个C#接口无法包容一个委托并把它当作成员;而event关键字引入的是一个新的成员,因此事件可以归人接口。理解这点,我们要从C#接口的使命说起,C#接口是一个契约,规范了接口实现者的行为,而不是要有些什么。很简单,例如“党员”是个接口,它肯定有个动作是“为人民服务”,“某某党员”实现了“党员”这个接口,那么“某某党员”肯定也要“为人民服务”,至于你“某某党员”是否必须拥用“电脑”、“小孩”。那么“党员”这个接口中肯定不会有规定。这也就是接口的目的,规范了实现者的一些行为。所以C#接口的成员都是方法,不会有其它了。稍有c#常识的程序员都明白,c#中的属性,其实就是两个方法,一个Set方法,一个Get方法,同样事件和索引器也都是方法,请看下面的接口:

public interface IDrawingObject

{

event EventHandler OnDraw;

string Name

{

get;

set;

}

int this[int index]

{

get;

set;

}

void SetValue();

}

该接口包含了c#接口所能接纳的所有成员,事件,属性,索引器,方法。把该接口编译后,我们用MSIL Disassembler工具查看一下:






这下大家都明白了,其实属性Name对应于Get_Name(),Set_Name()这两个方法,事件OnDraw对应于add_OnDraw(),remove_OnDraw()这两个方法,索引器对应于get_Item(),set_Item()这两个方法。在看下面的委托和类的定义:

public delegate void TestEventDelegate(object sender, System.EventArgs e);

class TestClass

{

public void SetValue()

{ }

}








看到了吧,定义一个委托和定义一个类是没有什么区别的,都是定义了个新的类型。所以C#接口是不能有委托的,除非微软告诉我们C#接口中是可以定义类的。


posted @ 2010-12-17 21:21 羽落无声 阅读(16) 评论(0)  编辑

转载自http://www.cnblogs.com/michaelxu/archive/2007/03/29/692021.html


什么是接口?其实,接口简单理解就是一种约定,使得实现接口的类或结构在形式上保持一致。个人觉得,使用接口可以使程序更加清晰和条理化,这就是接口的好处,但并不是所有的编程语言都支持接口,C#是支持接口的。注意,虽然在概念上,C#接口类似于COM接口,但他们的底层结构是不同的。那么,我们来看一下如何声明和使用接口。

  声明接口

  声明接口在语法上和声明抽象类完全相同,例如这里有一个银行账户的接口:
  
public interface IBankAccount
{
void PayIn(decimal amount);
bool Withdraw(decimal amount);

decimal Balance
{
get;
}
}

  注意:接口中只能包含方法、属性、索引器和事件的声明。不允许声明成员上的修饰符,即使是pubilc都不行,因为接口成员总是公有的,也不能声明为虚拟和静态的。如果需要修饰符,最好让实现类来声明。

  使用接口的例子

  这是书上的一个简单的例子,但足以说明接口的使用方法。
  一个银行账户的接口,两个不同银行账户的实现类,都继承于这个接口。接口声明如上。下面是两个账户类:

class SaverAccount : IBankAccount
{
private decimal balance;

public decimal Balance
{
get
{
return balance;
}
}

public void PayIn(decimal amount)
{
balance += amount;
}

public bool Withdraw(decimal amount)
{
if (balance >= amount)
{
balance -= amount;
return true;
}
Console.WriteLine("Withdraw failed.");
return false;
}

public override string ToString()
{
return String.Format("Venus Bank Saver:Balance={0,6:C}", balance);
}
}

class GoldAccount : IBankAccount
{
private decimal balance;

public decimal Balance
{
get
{
return balance;
}
}

public void PayIn(decimal amount)
{
balance += amount;
}

public bool Withdraw(decimal amount)
{
if (balance >= amount)
{
balance -= amount;
return true;
}
Console.WriteLine("Withdraw failed.");
return false;
}

public override string ToString()
{
return String.Format("Jupiter Bank Saver:Balance={0,6:C}", balance);
}
}

  可见,这两个实现类多继承了IBankAccount接口,因此它们必须要实现接口中的所有声明的方法。要不然,编译就会出错。让我们来测试一下,下面是测试代码:

static void Main(string[] args)
{
IBankAccount venusAccount = new SaverAccount();
IBankAccount jupiterAccount = new CurrentAccount();
venusAccount.PayIn(200);
jupiterAccount.PayIn(500);
Console.WriteLine(venusAccount.ToString());
jupiterAccount.PayIn(400);
jupiterAccount.Withdraw(500);
jupiterAccount.Withdraw(100);
Console.WriteLine(jupiterAccount.ToString());

}

  请注意开头两句,我们把它们声明为IBankAccount引用的方式,而没有声明为类的引用,为什么呢?因为,这样我们就可以让它指向执行这个接口的任何类的实例了,比较灵活。但这也有个缺点,如果我们要执行不属于接口的方法,比如这里重载的ToString()方法,就要先把接口的引用强制转换成合适的类型了。

  接口的继承

  接口也可以彼此继承,就象类的继承一样。比如我们又声明一个接口ITransferBankAccount,它继承于IBankAccount接口。

interface ITransferBankAccount : IBankAccount
{
bool TransferTo(IBankAccount destination, decimal amount);
}

  在这个接口中,又新增加了一个方法TransferTo(),所以如果我们要写一个类从ITransferBankAccount继承的话,就必须要实现IBankAccount和ITransferBankAccount两个接口所有的方法声明。即:

class CurrentAccount : ITransferBankAccount
{
private decimal balance;

public decimal Balance
{
get
{
return balance;
}
}

public void PayIn(decimal amount)
{
balance += amount;
}

public bool Withdraw(decimal amount)
{
if (balance >= amount)
{
balance -= amount;
return true;
}
Console.WriteLine("Withdraw failed.");
return false;
}

public override string ToString()
{
return String.Format("Jupiter Bank Saver:Balance={0,6:C}", balance);
}

public bool TransferTo(IBankAccount destination, decimal amount)
{
if (Withdraw(amount))
{
destination.PayIn(amount);
return true;
}
else
{
return false;
}
}
}

  总结起来说,使用C#接口应注意几个问题:

  1、C#中的接口是独立于类来定义的。这与 C++模型是对立的,在 C++中接口实际上就是抽象基类。

  2、接口和类都可以继承多个接口。

  3、类可以继承一个基类,接口根本不能继承类。这种模型避免了C++的多继承问题,C++中不同基类中的实现可能出现冲突。因此也不再需要诸如虚拟继承和显式作用域这类复杂机制。C#的简化接口模型有助于加快应用程序的开发。

  4、一个接口定义一个只有抽象成员的引用类型。C#中一个接口实际所做的,仅仅只存在着方法标志,但根本就没有执行代码。这就暗示了不能实例化一个接口,只能实例化一个派生自该接口的对象。

  5、接口可以定义方法、属性和索引。所以,对比一个类,接口的特殊性是:当定义一个类时,可以派生自多重接口,而你只能可以从仅有的一个类派生。

posted @ 2010-12-17 21:21 羽落无声 阅读(1) 评论(0)  编辑
indexof() :在字符串中从前向后定位字符和字符串;所有的返回值都是指在字符串的绝对位置,如为空则为- 1

string test="asdfjsdfjgkfasdsfsgfhgjgfjgdddd";

test.indexof('d') =2 //从前向后 定位 d 第一次出现的位置
test.indexof('d',1) =2 //从前向后 定位 d 从第三个字符串 第一次出现的位置
test.indexof('d',5,2) =6 //从前向后 定位 d 从第5 位开始查,查2位,即 从第5位到第7位;

lastindexof() :在字符串中从后向前定位字符和字符串;、
用法和 indexof() 完全相同。


下面介绍 IndexOfAny ||lastindexofany

他们接受字符数组做为变元,其他方法同上,返回数组中任何一个字符最早出现的下标位置

如下

char[] bbv={'s','c','b'};
string abc = "acsdfgdfgchacscdsad";

Response.Write(abc.IndexOfAny(bbv))=1
Response.Write(abc.IndexOfAny(bbv, 5))=9
Response.Write(abc.IndexOfAny(bbv, 5, 3))=9

lastindexofany 同上。
====================================================================
substring() 用法

string a="aadsfdjkfgklfdglfd"

a.substring(5) //截取从第五位以后的所有字符串

a.substring(0,5) //截取从第0位置开始长度为5的字符串
posted @ 2010-12-17 21:21 羽落无声 阅读(20) 评论(0)  编辑

看了此文,感觉大有收获,真是O(∩_∩)O谢谢楼主呀

http://dev.tot.name/dotnet/html/2008122/20081202161923.htm


相信大家都知道.net中有四个关于参数传入传出的类型 分别是:

System.Data.ParameterDirection.Input

System.Data.ParameterDirection.InputOutput

System.Data.ParameterDirection.Output

System.Data.ParameterDirection.ReturnValue

感官上理解就是只能传入 即可以传入又可以传出 只能传出 和 返回值 实际应用中和感官的理解一致吗?我也不大清楚 反正以前做的系统都没有遇见问题 所以也没有把这几个参数搞的很明白 不过心中始终有疑问 所以今天就抽了点时间做了一个例子把原理搞清楚

首先我把.Net中的参数定义为形式参数 而把存储过程的参数定义为实际参数

比如:cmd.Parameters.Add("@Input", System.Data.SqlDbType.Int); @Input为形式参数

而存储过程的@Input int,  @Input为实际参数



得到的结论如下:

数据库存储过程的实际参数如果没有默认值则形式参数必须传值给实际参数

但是如果形式参数的类型为ParameterDirection.Output 则传给实际参数的永远是空值

如果形式参数的类型为ParameterDirection.ReturnValue 则形式参数不会传值给实际参数 实际参数必须有默认值 否则代码会报错

如果形式参数类型为ParameterDirection.InputOutput 或者ParameterDirection.Output 则实际参数必须有output 关键字



另外需要注意的是在.net中 System.DBNull.Value表示数据库参数为空值 而不是null





用于测试的存储过程如下:



CREATE PROCEDURE proc_test_SQLParametersValue

@Input int,

@InputOutput int output,

@Output int output,

@ReturnValue int=1

AS

select @Input as Input,@InputOutput as InputOutput,@Output as [Output],@ReturnValue as ReturnValue

return 2

GO



测试用的C# 代码类如下:

using System;

using System.Collections.Generic;

using System.Text;

using System.Data.SqlClient;

using System.Configuration;

using System.Data;



namespace CoderHelper.Test

{

class SQLParametersValue

{

public SQLParametersValue()

{



}



public int? Input=1;

public int? InputOutput=2;

public int? Output=3;

public int? ReturnValue=4;



public int? Input2;

public int? InputOutput2;

public int? Output2;

public int? ReturnValue2;



public void GetData(DataTable dt)

{

SqlConnection conn = new SqlConnection(ConfigurationSettings.AppSettings["LocalSqlConnectionString"]);

SqlCommand cmd = new SqlCommand();

cmd.Connection = conn;

cmd.CommandType = System.Data.CommandType.StoredProcedure;

cmd.CommandText = "proc_test_SQLParametersValue";



cmd.Parameters.Add("@Input", System.Data.SqlDbType.Int);

cmd.Parameters["@Input"].Direction = System.Data.ParameterDirection.Input;

if (Input == null)

{

cmd.Parameters["@Input"].Value = System.DBNull.Value;

}

else

{

cmd.Parameters["@Input"].Value = Input;

}



cmd.Parameters.Add("@InputOutput", System.Data.SqlDbType.Int);

cmd.Parameters["@InputOutput"].Direction = System.Data.ParameterDirection.InputOutput;

if (InputOutput == null)

{

cmd.Parameters["@InputOutput"].Value = System.DBNull.Value;

}

else

{

cmd.Parameters["@InputOutput"].Value = InputOutput;

}



cmd.Parameters.Add("@Output", System.Data.SqlDbType.Int);

cmd.Parameters["@Output"].Direction = System.Data.ParameterDirection.Output;

if (Output == null)

{

cmd.Parameters["@Output"].Value = System.DBNull.Value;

}

else

{

cmd.Parameters["@Output"].Value = Output;

}



cmd.Parameters.Add("@ReturnValue", System.Data.SqlDbType.Int);

cmd.Parameters["@ReturnValue"].Direction = System.Data.ParameterDirection.ReturnValue;

if (ReturnValue == null)

{

cmd.Parameters["@ReturnValue"].Value = System.DBNull.Value;

}

else

{

cmd.Parameters["@ReturnValue"].Value = ReturnValue;

}



SqlDataAdapter sa = new SqlDataAdapter(cmd);

try

{

if (conn.State == System.Data.ConnectionState.Closed)

{

conn.Open();

}



sa.Fill(dt);



if (cmd.Parameters["@Input"].Value != System.DBNull.Value)

Input2 = Convert.ToInt32(cmd.Parameters["@Input"].Value);



if (cmd.Parameters["@InputOutput"].Value != System.DBNull.Value)

InputOutput2 = Convert.ToInt32(cmd.Parameters["@InputOutput"].Value);



if (cmd.Parameters["@Output"].Value != System.DBNull.Value)

Output2 = Convert.ToInt32(cmd.Parameters["@Output"].Value);



if (cmd.Parameters["@ReturnValue"].Value != System.DBNull.Value)

ReturnValue2 = Convert.ToInt32(cmd.Parameters["@ReturnValue"].Value);



}

catch (Exception ex)

{



}

finally

{

conn.Close();

}





}



}

}



如上代码

public int? Output=3; 但是实际传给存储过程的值还是空值

public int? ReturnValue=4; 但是实际没有传值给存储过程

ReturnValue2 = Convert.ToInt32(cmd.Parameters["@ReturnValue"].Value);取的是存储过程return的返回值此例存储过程代码是 return 2 所以取得值是2

posted @ 2010-12-17 21:21 羽落无声 阅读(71) 评论(0)  编辑
1.Asp.Net WebForm 用
“Request.PhysicalApplicationPath获取站点所在虚拟目录的物理路径,最后包含“\”;

2.C# WinForm 用
A:“Application.StartupPath”:获取当前应用程序所在目录的路径,最后不包含“\”;
B:“Application.ExecutablePath ”:获取当前应用程序文件的路径,包含文件的名称;
C:“AppDomain.CurrentDomain.BaseDirectory”:获取当前应用程序所在目录的路径,最后包含“\”;
D:“System.Threading.Thread.GetDomain().BaseDirectory”:获取当前应用程序所在目录的路径,最后包含“\”;
E:“Environment.CurrentDirectory”:获取当前应用程序的路径,最后不包含“\”;
F:“System.IO.Directory.GetCurrentDirectory”:获取当前应用程序的路径,最后不包含“\”;

3.C# Windows Service
用“AppDomain.CurrentDomain.BaseDirectory”或“System.Threading.Thread.GetDomain().BaseDirectory”;
用“Environment.CurrentDirectory”和“System.IO.Directory.GetCurrentDirectory”将得到“system32”目录的路径;
如果要使用“Application.StartupPath”或“Application.ExecutablePath”,需要手动添加对“System.Windows.Forms.dll ”的引用,并在程序开头用“using System.Windows.Forms”声明该引用;

4.在卸载程序获取系统安装的目录
System.Reflection.Assembly curPath = System.Reflection.Assembly.GetExecutingAssembly();
string path=curPath.Location;//得到安装程序类SetupLibrary文件的路径,获取这个文件路径所在的目录即得到安装程序的目录
posted @ 2010-12-17 21:21 羽落无声 阅读(14) 评论(0)  编辑

转载自http://www.qimao.cn/article.asp?id=179

qimao.cn
奇猫居-神游天地间

1. 获取当前进程的完整路径,包含文件名(进程名)。

this.GetType().Assembly.Location;
返回格式: X:\xxx\xxx\xxx.exe

2. 获取新的 Process 组件并将其与当前活动的进程关联的主模块的完整路径,包含文件名(进程名)。
System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName;
返回格式: X:\xxx\xxx\xxx.exe

3. 获取和设置当前目录(即该进程从中启动的目录)的完全限定路径。
System.Environment.CurrentDirectory;
返回格式: X:\xxx\xxx

4. 获取当前 Thread 的当前应用程序域的基目录,它由程序集冲突解决程序用来探测程序集。
System.AppDomain.CurrentDomain.BaseDirectory;
返回格式: X:\xxx\xxx\

5. 获取和设置包含该应用程序的目录的名称。
System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase;
返回格式: X:\xxx\xxx\ (.exe文件所在的目录+"\")

6. 获取启动了应用程序的可执行文件的路径,不包括可执行文件的名称。
System.Windows.Forms.Application.StartupPath;
返回格式: X:\xxx\xxx

7. 获取启动了应用程序的可执行文件的路径,包括可执行文件的名称。
System.Windows.Forms.Application.ExecutablePath;
返回格式: X:\xxx\xxx\xxx.exe

8.获取应用程序的当前工作目录。(注:此方法取值不固定,随着OpenFileDialog、SaveFileDialog等对象所确定的目录而改变,解决办法,程序启动时System.IO.Directory.GetCurrentDirectory()保存到变量里,需要程序所在路径是,使用变量值。)
System.IO.Directory.GetCurrentDirectory();
返回格式: X:\xxx\xxx

9. WebForm使用:获取站点所在虚拟目录的物理路径
Request.PhysicalApplicationPath
返回格式: X:\xxx\xxx

10. 在卸载程序获取系统安装的目录:
System.Reflection.Assembly curPath = System.Reflection.Assembly.GetExecutingAssembly();
string path=curPath.Location;//得到安装程序类SetupLibrary文件的路径,获取这个文件路径所在的目录即得到安装程序的目录
posted @ 2010-12-17 21:21 羽落无声 阅读(169) 评论(0)  编辑
我们写的程序当中,总有一些配置信息需要保存下来,以便完成程序的功能,最简单的办法就是将这些信息写入INI文件中,程序初始化时再读入.具体应用如下:
一.将信息写入.INI文件中.
1.所用的WINAPI函数原型为:
BOOL WritePrivateProfileString(
LPCTSTR lpAppName,
LPCTSTR lpKeyName,
LPCTSTR lpString,
LPCTSTR lpFileName
);
其中各参数的意义:
LPCTSTR lpAppName 是INI文件中的一个字段名.
LPCTSTR lpKeyName 是lpAppName下的一个键名,通俗讲就是变量名.
LPCTSTR lpString 是键值,也就是变量的值,不过必须为LPCTSTR型或CString型的.
LPCTSTR lpFileName 是完整的INI文件名.
2.具体使用方法:设现有一名学生,需把他的姓名和年龄写入 c:\stud\student.ini 文件中.
CString strName,strTemp;
int nAge;
strName="张三";
nAge=12;
::WritePrivateProfileString("StudentInfo","Name",strName,"c:\\stud\\student.ini");
此时c:\stud\student.ini文件中的内容如下:
[StudentInfo]
Name=张三
3.要将学生的年龄保存下来,只需将整型的值变为字符型即可:
strTemp.Format("%d",nAge);
::WritePrivateProfileString("StudentInfo","Age",strTemp,"c:\\stud\\student.ini");
二.将信息从INI文件中读入程序中的变量.
1.所用的WINAPI函数原型为:
DWORD GetPrivateProfileString(
LPCTSTR lpAppName,
LPCTSTR lpKeyName,
LPCTSTR lpDefault,
LPTSTR lpReturnedString,
DWORD nSize,
LPCTSTR lpFileName
);
其中各参数的意义:
前二个参数与 WritePrivateProfileString中的意义一样.
lpDefault : 如果INI文件中没有前两个参数指定的字段名或键名,则将此值赋给变量.
lpReturnedString : 接收INI文件中的值的CString对象,即目的缓存器.
nSize : 目的缓存器的大小.
lpFileName : 是完整的INI文件名.
2.具体使用方法:现要将上一步中写入的学生的信息读入程序中.
CString strStudName;
int nStudAge;
GetPrivateProfileString("StudentInfo","Name","默认姓名",strStudName.GetBuffer(MAX_PATH),MAX_PATH,"c:\\stud\\student.ini");
执行后 strStudName 的值为:"张三",若前两个参数有误,其值为:"默认姓名".
3.读入整型值要用另一个WINAPI函数:
UINT GetPrivateProfileInt(
LPCTSTR lpAppName,
LPCTSTR lpKeyName,
INT nDefault,
LPCTSTR lpFileName
);
这里的参数意义与上相同.使用方法如下:
nStudAge=GetPrivateProfileInt("StudentInfo","Age",10,"c:\\stud\\student.ini");
三.循环写入多个值,设现有一程序,要将最近使用的几个文件名保存下来,具体程序如下:
1.写入:
CString strTemp,strTempA;
int i;
int nCount=6;
file://共有6个文件名需要保存
for(i=0;i {strTemp.Format("%d",i);
strTempA=文件名;
file://文件名可以从数组,列表框等处取得.
::WritePrivateProfileString("UseFileName","FileName"+strTemp,strTempA,"c:\\usefile\\usefile.ini");
}
strTemp.Format("%d",nCount);
::WritePrivateProfileString("FileCount","Count",strTemp,"c:\\usefile\\usefile.ini");
file://将文件总数写入,以便读出.
2.读出:
nCount=::GetPrivateProfileInt("FileCount","Count",0,"c:\\usefile\\usefile.ini");
for(i=0;i {strTemp.Format("%d",i);
strTemp="FileName"+strTemp;
::GetPrivateProfileString("CurrentIni",strTemp,"default.fil", strTempA.GetBuffer(MAX_PATH),MAX_PATH,"c:\\usefile\\usefile.ini");
file://使用strTempA中的内容.
}
补充四点:
1.INI文件的路径必须完整,文件名前面的各级目录必须存在,否则写入不成功,该函数返回 FALSE 值.
2.文件名的路径中必须为 \\ ,因为在VC++中, \\ 才表示一个 \ .
3.也可将INI文件放在程序所在目录,此时 lpFileName 参数为: ".\\student.ini".
4.从网页中粘贴源代码时,最好先粘贴至记事本中,再往VC中粘贴,否则易造成编译错误,开始时我也十分不解,好好的代码怎么就不对呢?后来才找到这个方法.还有一些代码中使用了全角字符如:<,\等,也会造成编译错误.
VB没有直接读写INI文件的语句,必须借助Windows API来操作INI文件。相应的Windows API函数有两类:一类是GetProfileInt、GetProfileString、WriteProfileInt和WriteProfileString,它们是读写Win.ini中的设置;另一类是GetPrivateProfileInt、GetPrivateProfileString、WritePrivateProfileInt和WritePrivateProfileString,它们可以读写如何一个.ini文件。这些函数的声明都在Win32api.txt中找到。先在VB中建立一个模块,输入以下代码:
Declare Function GetPrivateProfileString Lib "kernel32" _
Alias "GetPrivateProfileStringA" (ByVal lpApplicationName _
As String, ByVal lpKeyName As Any, ByVal lpDefault As String, _
ByVal lpReturnedString As String, ByVal nSize As Long, _
ByVal lpFileName As String) As Long
Declare Function WritePrivateProfileString Lib "kernel32" _
Alias "WritePrivateProfileStringA" (ByVal lpApplicationName _
As String, ByVal lpKeyName As Any, ByVal lpString As Any, _
ByVal lpFileName As String) As Long
下面的例子将从njcom.ini中读取NJStar Communicator的目录。
Dim s As String * 256
GetPrivateProfileString "NJCOM Options", _
"Home Directory", "", s, 256, "njcom.ini"
Label1.Caption = s
下面的例子将利用WritePrivateProfileString删除掉njcom.ini中Home Directory设置。这里我们的第三个参数不是通常的字符串,而是0&,这里你可以看到我们在声明参数类型时使用As Any的好处。
WritePrivateProfileString "NJCOM Options", _
"Home Directory", 0&, "njcom.ini"
posted @ 2010-12-17 21:21 羽落无声 阅读(404) 评论(0)  编辑

转载自http://blog.526net.com/?p=21

INI文件就是扩展名为“ini”的文件。在Windows系统中,INI文件是很多,最重要的就是“System.ini”、“System32.ini”和“Win.ini”。该文件主要存放用户所做的选择以及系统的各种参数。用户可以通过修改INI文件,来改变应用程序和系统的很多配置。但自从Windows 95的退出,在Windows系统中引入了注册表的概念,INI文件在Windows系统的地位就开始不断下滑,这是因为注册表的独特优点,使应用程序和系统都把许多参数和初始化信息放进了注册表中。但在某些场合,INI文件还拥有其不可替代的地位。本文就来探讨一下C#是如何对INI进行读写操作。

INI文件的结构
INI文件是一种按照特点方式排列的文本文件。每一个INI文件构成都非常类似,由若干段落(section)组成,在每个带括号的标题下面,是若干个以单个单词开头的关键词(keyword)和一个等号,等号右边的就是关键字对应的值(value)。其一般形式如下:
[Section1]
  KeyWord1 = Valuel
  KeyWord2 = Value2
   ……
  [Section2]
  KeyWord3 = Value3
  KeyWord4 = Value4

本文中介绍的程序设计及运行环境:


● 微软视窗2000 高级服务器版

● .Net Framework SDK正式版
C#和Win32 API函数
C#并不像C++,拥有属于自己的类库。C#使用的类库是.Net框架为所有.Net程序开发提供的一个共有的类库——.Net FrameWork SDK。虽然.Net FrameWork SDK内容十分庞大,功能也非常强大,但还不能面面俱到,至少它并没有提供直接操作INI文件所需要的相关的类。在本文中,C#操作INI文件使用的是Windows系统自带Win32的API函数——WritePrivateProfileString()和GetPrivateProfileString()函数。这二个函数都位于“kernel32.dll”文件中。


我们知道在C#中使用的类库都是托管代码(Managed Code)文件,而Win32的API函数所处的文件,都是非托管代码(Unmanaged Code)文件。这就导致了在C#中不可能直接使用这些非托管代码文件中的函数。好在.Net框架为了保持对下的兼容,也为了充分利用以前的资源,提出了互操作,通过互操作可以实现对Win32的API函数的调用。互操作不仅适用于Win32的API函数,还可以用来访问托管的COM对象。C#中对Win32的API函数的互操作是通过命名空间“System.Runtime.InteropServices”中的“DllImport”特征类来实现的。它的主要作用是指示此属性化方法是作为非托管DLL的输出实现的。下面代码就是在C#利用命名空间“System.Runtime.InteropServices”中的“DllImport”特征类申明上面二个Win32的API函数:

C#申明INI文件的写操作函数WritePrivateProfileString():[ DllImport ( "kernel32" ) ]
private static extern long WritePrivateProfileString ( string
section ,
string key , string val , string filePath ) ;

参数说明:section:INI文件中的段落;key:INI文件中的关键字;val:INI文件中关键字的数值;filePath:INI文件的完整的路径和名称。


C#申明INI文件的读操作函数GetPrivateProfileString():[ DllImport ( "kernel32" ) ]
private static extern int GetPrivateProfileString ( string section ,
string key , string def , StringBuilder retVal ,
int size , string filePath ) ;



参数说明:section:INI文件中的段落名称;key:INI文件中的关键字;def:无法读取时候时候的缺省数值;retVal:读取数值;size:数值的大小;filePath:INI文件的完整路径和名称。
C#对INI文件进行写操作代码:
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.IO;
namespace INIFileTest
{
public partial class Form1 : Form
{
[DllImport("kernel32")]
private static extern long WritePrivateProfileString(string section, string key,
string val, string filePath);

[DllImport("kernel32")]
private static extern int GetPrivateProfileString(string section, string key,
string def, StringBuilder retVal,
int size, string filePath);

string FileName = @”..\..\test.ini”;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{

WritePrivateProfileString(“段落名称一”, “键一”, “值一”, FileName);
WritePrivateProfileString(“段落名称二”, “键二”, “值二”, FileName);
WritePrivateProfileString(“段落名称三”, “键三”, “值三”, FileName);
MessageBox.Show(“成功写入INI文件!”, “信息”);
}
private void button2_Click(object sender, EventArgs e)
{

StringBuilder temp = new StringBuilder(255);
int i = GetPrivateProfileString(“段落名称一”, “键一”, “无法读取对应数值!”,
temp, 255, FileName);
int jj = temp.Length;
MessageBox.Show(“键一=” + temp.ToString());
}
private void button3_Click(object sender, EventArgs e)
{
//删除一个键值
WritePrivateProfileString(“段落名称一”, “键一”, null, FileName);
//删除一个段落
WritePrivateProfileString(“段落名称一”, null, null, FileName);
}
}
}
posted @ 2010-12-17 21:21 羽落无声 阅读(198) 评论(0)  编辑
配置文件中经常用到ini文件,在VC中其函数分别为:

#include <Windows.h> //wince,WMobile.ppc不支持这几个函数

写入.ini文件:bool WritePrivateProfileString(LPCTSTR lpAppName, LPCTSTR lpKeyName, LPCTSTR lpString, LPCTSTR lpFileName);


读取.ini文件:DWORD GetPrivateProfileString(LPCTSTR lpAppName, LPCTSTR lpKeyName, LPCTSTR lpDefaut, LPSTR lpReturnedString, DWORD nSize, LPCTSTR lpFileName);函数返回值为string的长度(long型),而从ini文件获得的字符串则保留在目的缓冲器中

读取整形值:UINT GetPrivateProfileInt(LPCTSTR lpAppName,LPCTSTR lpKeyName,INT nDefault,LPCTSTR lpFileName);

其中个参数的意思:

LPCTSTR lpAppName ------- INI文件中的一个字段名

LPCTSTR lpKeyName -------- lpAppName 下的一个键名,也就是里面具体的变量名

LPCTSTR lpDefaut ----------如果没有其前两个参数值,则将此值赋给变量

LPSTR lpReturnedString --------接收INI文件中的值的CString对象,即接收缓冲区

DWORD nSize ------接收缓冲区的大小

LPCTSTR lpFileName --------完整的INI文件路径名

LPCTSTR lpString ---------是键值,也就是变量的值, 必须为LPCTSTR或CString类型

例子:

CString StrName,Strtemp;

int nAge;

StrName = "jacky";

nAge = 13;

WritePrivateProfileString("Student","Name",StrName,"c:\\setting.ini");

结果:(INI文件中显示如下:)

[Student]

Name=jacky

读取:

CString str;

GetPrivateProfileString(
CString("Student"),
CString("Name"),
CString("NULL"),
str.GetBuffer(MAX_LENGTH),
MAX_LENGTH,
CString("F:\\Program\\Test_Read_ini\\debug\\hello.ini")
);

结果:str = "jacky";这里需要注意点就是用完GetBuffer函数后一定要释放(用str.ReleaseBuffer()函数),不然后面再用到SName的其他子函数就会失灵。

3.读入整型值要用另一个WINAPI函数:
UINT GetPrivateProfileInt(
LPCTSTR lpAppName,
LPCTSTR lpKeyName,
INT nDefault,
LPCTSTR lpFileName
);
  这里的参数意义与上相同.使用方法如下:

nStudAge=GetPrivateProfileInt("StudentInfo","Age",10,"c:\\stud\\student.ini");

在GetPrivateProfileString最后一个参数是配置文件路径的参数,此路径只能是绝对路径,不能是相对路径,但现在我需要是我的exe文件能和我的配置文件在一起。因此我使用了GetCurrentDirectory函数。

原代码如下:

CString server_ip;
CString des="";
::GetCurrentDirectory(MAX_PATHLENGTH,des.GetBuffer(MAX_PATHLENGTH));
des.ReleaseBuffer();
des+="\\config.ini";
GetPrivateProfileString("PhoneDemo","Server_IP","",server_ip.GetBufferSetLength(15),15,des);
server_ip.ReleaseBuffer();

注意:在这里使用CString变量时,在使用完GetBuffer后,紧接着一定要使用ReleaseBuffer()函数,才可以进行其他的诸如字符串+操作

 补充四点:

   1.INI文件的路径必须完整,文件名前面的各级目录必须存在,否则写入不成功,该函数返回 FALSE 值.

   2.文件名的路径中必须为 \\ ,因为在VC++中, \\ 才表示一个 \ .

   3.也可将INI文件放在程序所在目录,此时 lpFileName 参数为: ".\\student.ini".

   4.从网页中粘贴源代码时,最好先粘贴至记事本中,再往VC中粘贴,否则易造成编译错误,开始时我也十分不解,好好的代码怎么就不对呢?后来才找到这个方法.还有一些代码中使用了全角字符如:<,\等,也会
造成编译错误.

INI文件编程

INI文件在系统配置及应用程序参数保存与设置方面,具有很重要的作用,所以可视化的编程一族,如VB、VC、VFP、Delphi等都提供了读写INI文件的方法,其中Delphi中操作INI文件,最为简洁,这是因为Delphi3提供了一个TInifile类,使我们可以非常灵活的处理INI文件。

一、有必要了解INI文件的结构:
;注释
[小节名]
关键字=值
...
  INI文件允许有多个小节,每个小节又允许有多个关键字, "="后面是该关键字的值。
  值的类型有三种:字符串、整型数值和布尔值。其中字符串存贮在INI文件中时没有引号,
布尔真值用1表示,布尔假值用0表示。
  注释以分号";"开头。
二、定义
  1、在Interface的Uses节增加IniFiles;
  2、在Var变量定义部分增加一行:
myinifile:Tinifile;
  然后,就可以对变量myinifile进行创建、打开、读取、写入等操作了。

三、打开INI文件


myinifile:=Tinifile.create('program.ini');


  上面这一行语句将会为变量myinifile与具体的文件program.ini建立联系,然后,就可以通过变量myinifile,来读写program.ini文件中的关键字的值了。值得注意的是,如果括号中的文件名没有指明路径的话,那么这个Program.ini文件会存储在Windows目录中,把Program.ini文件存储在应用程序当前目录中的方法是:为其指定完整的路径及文件名。下面的两条语句可以完成这个功能:

Filename:=ExtractFilePath(Paramstr(0))+'program.ini';

myinifile:=Tinifile.Create(filename);

四、读取关键字的值
  针对INI文件支持的字符串、整型数值、布尔值三种数据类型,TINIfiles类提供了三种不同的对象方法来读取INI文件中关键字的值。
  假设已定义变量vs、vi、vb分别为string、 integer、boolean类型。

vs:=myinifile.Readstring('小节名','关键字',缺省值);
vi:=myinifile.Readinteger('小节名','关键字',缺省值);
vb:=myinifile.Readbool('小节名','关键字',缺省值);

  其中缺省值为该INI文件不存在该关键字时返回的缺省值。

五、写入INI文件
  同样的,TInifile类也提供了三种不同的对象方法,向INI文件写入字符串、整型数及布尔类型的关键字。

myinifile.writestring('小节名','关键字',变量或字符串值);
myinifile.writeinteger('小节名','关键字',变量或整型数值);
myinifile.writebool('小节名','关键字',变量或True或False);
  当这个INI文件不存在时,上面的语句还会自动创建该INI文件。
六、删除关键字
  除了可用写入方法增加一个关键字,Tinifile类还提供了一个删除关键字的对象方法:
myinifile.DeleteKey('小节名','关键字');

七、小节操作
  增加一个小节可用写入的方法来完成,删除一个小节可用下面的对象方法:
myinifile.EraseSection('小节名');
  另外Tinifile类还提供了三种对象方法来对小节进行操作:
 myinifile.readsection('小节名',TStrings变量);可将指定小节中的所有关键字名读取至一个字符串列表变量中;
 myinifile.readsections(TStrings变量);可将INI文件中所有小节名读取至一个字符串列表变量中去。
 myinifile.readsectionvalues('小节名',TStrings变量);可将INI文件中指定小节的所有行(包括关键字、=、值)读取至一个字符串列表变量中去。

八、释放
在适当的位置用下面的语句释放myinifile:
myinifile.distory;
九、一个实例
  下面用一个简单的例子(如图),演示了建立、读取、存贮INI文件的方法。myini.ini文件中包含有"程序参数"小节,和用户名称(字符串)、是否正式用户(布尔值)和已运行时间(整型值)三个关键字。程序在窗体建立读取这些数据,并在窗体释放时写myini.ini文件。
  附源程序清单
unit Unit1;
interface
uses
Windows,Messages,SysUtils,Classes,Graphics,Controls,Forms,Dialogs,inifiles,StdCtrls,ExtCtrls;

type
TForm1 = class(TForm)
Edit1: TEdit;
CheckBox1: TCheckBox;
Edit2: TEdit;
Label1: TLabel;
Label2: TLabel;
Timer1: TTimer;
Label3: TLabel;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;

implementation
var
myinifile:TInifile;
{$R *.DFM}

procedure TForm1.FormCreate(Sender: TObject);
var filename:string;
begin
filename:=ExtractFilePath(paramstr(0))+'myini.ini';
myinifile:=TInifile.Create(filename);
edit1.Text:= myinifile.readstring('程序参数','用户名称','缺省的用户名称');
edit2.text:= inttostr(myinifile.readinteger('程序参数','已运行时间',0));
checkbox1.Checked:= myinifile.readbool('程序参数','是否正式用户',False);
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
myinifile.writestring('程序参数','用户名称',edit1.Text);

myinifile.writeinteger('程序参数','已运行时间',strtoint(edit2.text));
myinifile.writebool('程序参数','是否正式用户',checkbox1.Checked);
myinifile.Destroy;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
edit2.Text:=inttostr(strtoint(edit2.text)+1);
end;

end.
  程序在Pwin95、Delphi3下调试通过。
posted @ 2010-12-17 21:21 羽落无声 阅读(480) 评论(0)  编辑

转载自http://www.cnblogs.com/redfox241/archive/2007/05/05/736540.html

这两天一直被一个问题困扰着,就是 我用一个combox显示数据,并根据用户的选择,触发SelectedIndexChanged事件完成一些操作,但是

当用combox数据绑定到一个dataset时就触发了SelectedIndexChanged事件,请教如何在数据绑定时不让combox控件触发SelectedIndexChanged事件,
本来想设个Flag变量,判断是不是第一次登录,那样也可以,不过我不喜欢,后来看到网上有说用“事件”解决。
做个试验,真好使
代码如下:

1 //解除事件
2 this.cboVendor.SelectedIndexChanged -= new System.EventHandler(this.cboVendor_SelectedIndexChanged);
3 cboVendor.DataSource = myClass.RunQueryCmd(strSqlCmd);
4 cboVendor.DisplayMember = "SupplierCode";
5 //添加事件
6 this.cboVendor.SelectedIndexChanged += new System.EventHandler(this.cboVendor_SelectedIndexChanged);
这个问题就解决拉!!!
posted @ 2010-12-17 21:21 羽落无声 阅读(260) 评论(0)  编辑

通过vs自动生成的强类型dataset代码,我截取看了一段自动生成的代码

//以下代码是我自定义了一段update 操作vs自动生成的

public virtual int ResetErrortimes(int id) {
global::System.Data.SqlClient.SqlCommand command = this.CommandCollection[3];
command.Parameters[0].Value = ((int)(id));
global::System.Data.ConnectionState previousConnectionState = command.Connection.State;
if (((command.Connection.State& global::System.Data.ConnectionState.Open)
!= global::System.Data.ConnectionState.Open)
) {
command.Connection.Open();
}
int returnValue;
try {
returnValue = command.ExecuteNonQuery();
}
finally {
if ((previousConnectionState == global::System.Data.ConnectionState.Closed)) {
command.Connection.Close();
}
}
return returnValue;
}

这段代码仔细阅读后发现很精巧,我们知道,打开连接操作时十分耗时的,如果我们要对数据库进行批量操作时,我们通过对这段代码特性的了解,可以首先自己打开链接,平批量操作结束时再自己关闭即可。

adapter.connection.open();

adapter.connection.close();

我们可以用stopwatch类来查看一下执行时间:

stopwatch sw=new stopwatch();

sw.start();

……

sw.stop();

messagebox.shoe(sw.elapsed.tostring());


posted @ 2010-12-17 21:21 羽落无声 阅读(21) 评论(0)  编辑
DataSet:数据集。一般包含多个DataTable,用的时候,dataset["表名"]得到DataTable
DataTable:数据表。
一:
SqlDataAdapter da=new SqlDataAdapter(cmd);
DataTable dt=new DataTable();
da.Fill(dt);
-----------------
直接把数据结果放到datatable中,
二:
SqlDataAdapter da=new SqlDataAdapter(cmd);
DataSet dt=new DataSet();
da.Fill(dt);
----------------
数据结果放到dataset中,若要用那个datatable,可以这样:dataset[0]
更常见的用法:
SqlDataAdapter da=new SqlDataAdapter(cmd);
DataSet dt=new DataSet();
da.Fill(dt,"table1");
用的时候:这样取datatable:

dataset["table1"]


posted @ 2010-12-17 21:21 羽落无声 阅读(7) 评论(0)  编辑
数据库中的数字和编程语言中的数字有显著不同的特征,因为数据库中的数字可以为空,C#中的数字不能为空。Int32是一个结构,而结构是值类型的,所以它不能为空。



在C#中可以使用Nullable<T>结构很容易解决这个问题。

定义可空类型:1 Nullable<int> x;
2 int? x2;




可以检查Nullable<T>的HasValue和Value属性01 Nullable<int> x;
02
03 x = 4;
04 x += 3;
05
06 if (x.HasValue)
07 {
08 int y = x.Value;
09 }
10
11 x = null;

判断它是否为空可以用两种方法

1、==null

2、.HasValue

将可空数据赋值给非空也有两种方法

int? i3 = null;

1、int i4 = i3.Value;

2、int i4=(int)i3;


posted @ 2010-12-17 21:21 羽落无声 阅读(47) 评论(0)  编辑

今天自己编了一SQLHelper类,打算试试测试一下,却遇到一奇怪的问题

这是其中的一部分public static DataTable ExecuteDataTable(string sql, params SqlParameter[] parameters)
{
string connStr = ConfigurationManager.ConnectionStrings["ConStr"].ConnectionString;
using (SqlConnection conn = new SqlConnection(connStr))
{
conn.Open();
using (SqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = sql;
foreach (SqlParameter sqlParameter in parameters)
{
cmd.Parameters.Add(sqlParameter);
}
DataSet dataSet = new DataSet();
SqlDataAdapter adapter = new SqlDataAdapter(cmd);
adapter.Fill(dataSet);
return dataSet.Tables[0];
}
}
}

我执行了这么一个语句

SQLHelper.ExecuteDataTable("select * from Login where id=@id", new SqlParameter("@id",0));

却有了如下错误

未处理的“System.Data.SqlClient.SqlException”类型的异常出现在 System.Data.dll中。

其他信息: 参数化查询 '(@id bigint)select * from Login where id=@id' 需要参数'@id',但未提供该参数。


其实原因很简单。

这里涉及到sqlParameter的两种构造函数,我们只需在0前面强制类型为object即可



 
 


posted @ 2010-12-17 21:21 羽落无声 阅读(60) 评论(0)  编辑
posted @ 2010-12-17 21:21 羽落无声 阅读(58) 评论(0)  编辑

今天尝试封装了一些标准数据库操作,也为以后能自己做一套.dll动态链接库做准备。

却无奈遇到了一个问题

class SQLHelper

{

public static SqlDataReader ExecuteReader(string sql, params SqlParameter[] parameters)
{
string connStr = ConfigurationManager.ConnectionStrings["ConStr"].ConnectionString;
using (SqlConnection conn = new SqlConnection(connStr))
{
conn.Open();
using (SqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = sql;
foreach (SqlParameter sqlParameter in parameters)
{
cmd.Parameters.Add(sqlParameter);
}
return cmd.ExecuteReader();
}
}
}

private void btnExecuteReader_Click(object sender, EventArgs e)
{
SqlDataReader reader = SQLHelper.ExecuteReader("select * from T_person");
while (reader.Read())
{
string name=reader.GetString(reader.GetOrdinal("name"));
MessageBox.Show(name);
}
}

原因很简单

DataReader相当于一个只能向前的读取器,在读取的时候你不能conn.close(),而在函数调用结束时,reader已经被Close()了。
因此,一般的做法是返回一个IList。

当然还有更一般的做法:

因为SqlDataReader对于小数据量的数据来说带来的只有麻烦,有点可疑忽略不计。

所以改而使用DataSet,将查询结果填充到本地内存,这样即使链接断开,也没有影响。

更改如下;

private void btnDataset_Click(object sender, EventArgs e)
{
string connStr = ConfigurationManager.ConnectionStrings["ConStr"].ConnectionString;
using (SqlConnection conn = new SqlConnection(connStr))
{
conn.Open();
using (SqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = "select * from T_person";
DataSet dataSet=new DataSet();
SqlDataAdapter adapter=new SqlDataAdapter(cmd);
adapter.Fill(dataSet);
DataTable table=dataSet.Tables[0];
for (int i = 0; i < table.Rows.Count;i++ )
{
DataRow row = table.Rows[i];
string name = Convert.ToString(row["name"]);
MessageBox.Show(name);
}
}
}
}


大家也可以看看csdn上的一个帖子

http://topic.csdn.net/u/20090419/23/5e5030f4-7201-430a-a786-3dd7d4f1699a.html

posted @ 2010-12-17 21:21 羽落无声 阅读(1282) 评论(1)  编辑

Data Developer Center > Data Platform Development Forums > ADO.NET DataSet 上有一篇问答讲的很好

这是她的网址http://social.msdn.microsoft.com/Forums/en/adodotnetdataset/thread/1faff35e-055b-4728-a6c8-ece257585ab7

在我们平时的简单应用中,或者是刚开始学习使用ADO.NET,用基于服务的数据库会方便一些,但也给我们带来了一些困难,这里我重点讲一个好多新手会遇到的问题,

那就是,我建立了一个基于服务的数据库 database1.mdf

string connstr = ConfigurationManager.ConnectionStrings["constr"].ConnectionString;
using(SqlConnection conn=new SqlConnection(connstr))
{
conn.Open();
using(SqlCommand cmd=conn.CreateCommand())
{
cmd.CommandText = "delete from T_Mobile";
cmd.ExecuteNonQuery();

string[] files = Directory.GetFiles(path, "*txt", SearchOption.TopDirectoryOnly);
foreach (string file in files)
{
//string title=Path.GetFileNameWithoutExtension();
using(FileStream fileStream=File.OpenRead(file))
{
using(StreamReader streamReader=new StreamReader(fileStream,System.Text.Encoding.Default))
{
string line = null;
while ((line=streamReader.ReadLine())!=null)
{
string[] strs = line.Split(',');
int startNo = Convert.ToInt32(strs[1]);
int code = Convert.ToInt32(strs[2]);
string city = strs[3];
string cardType = strs[4];
cmd.Parameters.Clear();
cmd.CommandText = "insert into T_Mobile(startNo,code,city,cardType) values(@startNo,@code,@city,@cardType)";
cmd.Parameters.Add(new SqlParameter("@startNo", startNo));
cmd.Parameters.Add(new SqlParameter("@code", code));
cmd.Parameters.Add(new SqlParameter("@city", city));
cmd.Parameters.Add(new SqlParameter("@cardType", cardType));
cmd.ExecuteNonQuery();
}
}
}
}
}
}

从选取的文件夹中读出了所有她的.txt文件,并把它存入数据库(事实上,这正是我学习ADO.NET时的一个练习——手机号码归属地查询)成功后我却没有在表中看见数据,真相很简单,c#默认存储在\bin\Debug下了,所以我们只需在入口函数处添加一段代码

//Program.cs

using System.Windows.Forms;

namespace MobileAscription
{
static class Program
{
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main()
{
string dataDir = AppDomain.CurrentDomain.BaseDirectory;
if (dataDir.EndsWith(@"\bin\Debug\") || dataDir.EndsWith(@"\bin\Release"))
{
dataDir = System.IO.Directory.GetParent(dataDir).Parent.Parent.FullName;
AppDomain.CurrentDomain.SetData("DataDirectory", dataDir);
}


Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
}

切记要加载入口函数的最开始!!

posted @ 2010-12-17 21:21 羽落无声 阅读(348) 评论(0)  编辑

首先O(∩_∩)O谢谢一品梅分享了自己的经验,这是他的blog原文地址

http://www.cnblogs.com/onlyendure/archive/2008/03/25/1121247.html


在编写文本文件读写程序的过程中,有如下代码

StreamReader sr = new StreamReader(FileName);
结果发现打开中文文本文件出现乱码。

究其原因,原来自从Windows 2000之后的操作系统在文件处理时默认编码采用Unicode,所以.Net的文件默认编码也是Unicode。除非另外指定,StreamReader 的默认编码为 Unicode,而不是当前系统的 ANSI代码页。但是文档大部分还是以ANSI编码储存,中文文本使用的是gb2312,所以才造成中文乱码的状况,也就是说在读取文本的时候要指定编码格式。

但是问题来了,System.Text.Encoding 里面一堆编码格式ASCII、UTF-8等等,要选哪一个好?

其实很简单,用
System.Text.Encoding.Default 告诉
StreamReader 目前操作系统的编码即可。

StreamReader reader = new StreamReader(FileName, System.Text.Encoding.Default)
posted @ 2010-12-17 21:21 羽落无声 阅读(94) 评论(0)  编辑

http://www.programfan.com/blog/article.asp?id=28128


[引用:地址不明确了!]

--不足:23山东和16山东重复
--创建DBPromary数据库
create database DBPromary
use DBPromary
go

--创建promary表
create table promary
(
proID int primary key,
proName varchar(50) not null
)

----------------------------------------------------------------------------------------------------------------------------------------
--中国34个省级行政单位 23个省 5个自治区 4个直辖市 2特别行政区
insert into promary values(1,'北京市')
insert into promary values(2,'天津市')
insert into promary values(3,'上海市')
insert into promary values(4,'重庆市')
insert into promary values(5,'河北省')
insert into promary values(6,'山西省')
insert into promary values(7,'台湾省')
insert into promary values(8,'辽宁省')
insert into promary values(9,'吉林省')
insert into promary values(10,'黑龙江省')
insert into promary values(11,'江苏省')
insert into promary values(12,'浙江省')
insert into promary values(13,'安徽省')
insert into promary values(14,'福建省')
insert into promary values(15,'江西省')
insert into promary values(16,'山东省')
insert into promary values(17,'河南省')
insert into promary values(18,'湖北省')
insert into promary values(19,'湖南省')
insert into promary values(20,'广东省')
insert into promary values(21,'甘肃省')
insert into promary values(22,'四川省')
--insert into promary values(23,'山东省')
insert into promary values(24,'贵州省')
insert into promary values(25,'海南省')
insert into promary values(26,'云南省')
insert into promary values(27,'青海省')
insert into promary values(28,'陕西省')
insert into promary values(29,'广西壮族自治区')
insert into promary values(30,'西藏自治区')
insert into promary values(31,'宁夏回族自治区')
insert into promary values(32,'新疆维吾尔自治区')
insert into promary values(33,'内蒙古自治区')
insert into promary values(34,'澳门特别行政区')
insert into promary values(35,'香港特别行政区')
----------------------------------------------------------------------------------------------------------------------------------------

--创建city表
create table city
(
cityID int not null,
cityName varchar(50) primary key,
proID int foreign key references promary(proID)
)


----------------------------------------------------------------------------------------------------------------------------------------
--插入各个省的城市数据
--4个直辖市
insert into city values(1,'北京市',1)
insert into city values(1,'天津市',2)
insert into city values(1,'上海市',3)
insert into city values(1,'重庆市',4)
--5河北省(2005年辖:11个地级市,36个市辖区、22个县级市、108个县、6个自治县)
insert into city values(1,'石家庄市',5)
insert into city values(2,'唐山市',5)
insert into city values(3,'秦皇岛市',5)
insert into city values(4,'邯郸市',5)
insert into city values(5,'邢台市',5)
insert into city values(6,'保定市',5)
insert into city values(7,'张家口市',5)
insert into city values(8,'承德市',5)
insert into city values(9,'沧州市',5)
insert into city values(10,'廊坊市',5)
insert into city values(11,'衡水市',5)
--6山西省11个城市
insert into city values(1,'太原市',6)
insert into city values(2,'大同市',6)
insert into city values(3,'阳泉市',6)
insert into city values(4,'长治市',6)
insert into city values(5,'晋城市',6)
insert into city values(6,'朔州市',6)
insert into city values(7,'晋中市',6)
insert into city values(8,'运城市',6)
insert into city values(9,'忻州市',6)
insert into city values(10,'临汾市',6)
insert into city values(11,'吕梁市',6)
--7台湾省(台湾本岛和澎湖共设7市、16县,其中台北市和高雄市为“院辖市”,直属“行政院”,其余属台湾省;市下设区,县下设市(县辖市)、镇、乡,合称区市镇乡。)
insert into city values(1,'台北市',7)
insert into city values(2,'高雄市',7)
insert into city values(3,'基隆市',7)
insert into city values(4,'台中市',7)
insert into city values(5,'台南市',7)
insert into city values(6,'新竹市',7)
insert into city values(7,'嘉义市',7)
insert into city values(8,'台北县',7)
insert into city values(9,'宜兰县',7)
insert into city values(10,'桃园县',7)
insert into city values(11,'新竹县',7)
insert into city values(12,'苗栗县',7)
insert into city values(13,'台中县',7)
insert into city values(14,'彰化县',7)
insert into city values(15,'南投县',7)
insert into city values(16,'云林县',7)
insert into city values(17,'嘉义县',7)
insert into city values(18,'台南县',7)
insert into city values(19,'高雄县',7)
insert into city values(20,'屏东县',7)
insert into city values(21,'澎湖县',7)
insert into city values(22,'台东县',7)
insert into city values(23,'花莲县',7)
--8辽宁省(2006年,辖:14个地级市;56个市辖区、17个县级市、19个县、8个自治县。)
insert into city values(1,'沈阳市',8)
insert into city values(2,'大连市',8)
insert into city values(3,'鞍山市',8)
insert into city values(4,'抚顺市',8)
insert into city values(5,'本溪市',8)
insert into city values(6,'丹东市',8)
insert into city values(7,'锦州市',8)
insert into city values(8,'营口市',8)
insert into city values(9,'阜新市',8)
insert into city values(10,'辽阳市',8)
insert into city values(11,'盘锦市',8)
insert into city values(12,'铁岭市',8)
insert into city values(13,'朝阳市',8)
insert into city values(14,'葫芦岛市',8)
--9吉林省(2006年,辖:8个地级市、1个自治州;20个市辖区、20个县级市、17个县、3个自治县。)
insert into city values(1,'长春市',9)
insert into city values(2,'吉林市',9)
insert into city values(3,'四平市',9)
insert into city values(4,'辽源市',9)
insert into city values(5,'通化市',9)
insert into city values(6,'白山市',9)
insert into city values(7,'松原市',9)
insert into city values(8,'白城市',9)
insert into city values(9,'延边朝鲜族自治州',9)
--10黑龙江省(2006年,辖:12地级市、1地区;64市辖区、18县级市、45县、1自治县)
insert into city values(1,'哈尔滨市',10)
insert into city values(2,'齐齐哈尔市',10)
insert into city values(3,'鹤 岗 市',10)
insert into city values(4,'双鸭山市',10)
insert into city values(5,'鸡 西 市',10)
insert into city values(6,'大 庆 市',10)
insert into city values(7,'伊 春 市',10)
insert into city values(8,'牡丹江市',10)
insert into city values(9,'佳木斯市',10)
insert into city values(10,'七台河市',10)
insert into city values(11,'黑 河 市',10)
insert into city values(12,'绥 化 市',10)
insert into city values(13,'大兴安岭地区',10)
--11江苏省(2005年辖:13个地级市;54个市辖区、27个县级市、25个县)
insert into city values(1,'南京市',11)
insert into city values(2,'无锡市',11)
insert into city values(3,'徐州市',11)
insert into city values(4,'常州市',11)
insert into city values(5,'苏州市',11)
insert into city values(6,'南通市',11)
insert into city values(7,'连云港市',11)
insert into city values(8,'淮安市',11)
insert into city values(9,'盐城市',11)
insert into city values(10,'扬州市',11)
insert into city values(11,'镇江市',11)
insert into city values(12,'泰州市',11)
insert into city values(13,'宿迁市',11)
--12浙江省(2006年,辖:11个地级市;32个市辖区、22个县级市、35个县、1个自治县。)
insert into city values(1,'杭州市',12)
insert into city values(2,'宁波市',12)
insert into city values(3,'温州市',12)
insert into city values(4,'嘉兴市',12)
insert into city values(5,'湖州市',12)
insert into city values(6,'绍兴市',12)
insert into city values(7,'金华市',12)
insert into city values(8,'衢州市',12)
insert into city values(9,'舟山市',12)
insert into city values(10,'台州市',12)
insert into city values(11,'丽水市',12)
--13安徽省(2005年辖:17个地级市;44个市辖区、5县个级市、56个县。)
insert into city values(1,'合肥市',13)
insert into city values(2,'芜湖市',13)
insert into city values(3,'蚌埠市',13)
insert into city values(4,'淮南市',13)
insert into city values(5,'马鞍山市',13)
insert into city values(6,'淮北市',13)
insert into city values(7,'铜陵市',13)
insert into city values(8,'安庆市',13)
insert into city values(9,'黄山市',13)
insert into city values(10,'滁州市',13)
insert into city values(11,'阜阳市',13)
insert into city values(12,'宿州市',13)
insert into city values(13,'巢湖市',13)
insert into city values(14,'六安市',13)
insert into city values(15,'亳州市',13)
insert into city values(16,'池州市',13)
insert into city values(17,'宣城市',13)
--14福建省(2006年辖:9个地级市;26个市辖区、14个县级市、45个县。)
insert into city values(1,'福州市',14)
insert into city values(2,'厦门市',14)
insert into city values(3,'莆田市',14)
insert into city values(4,'三明市',14)
insert into city values(5,'泉州市',14)
insert into city values(6,'漳州市',14)
insert into city values(7,'南平市',14)
insert into city values(8,'龙岩市',14)
insert into city values(9,'宁德市',14)
--15江西省(2006年全省辖:11个地级市;19个市辖区、10个县级市、70个县。)
insert into city values(1,'南昌市',15)
insert into city values(2,'景德镇市',15)
insert into city values(3,'萍乡市',15)
insert into city values(4,'九江市',15)
insert into city values(5,'新余市',15)
insert into city values(6,'鹰潭市',15)
insert into city values(7,'赣州市',15)
insert into city values(8,'吉安市',15)
insert into city values(9,'宜春市',15)
insert into city values(10,'抚州市',15)
insert into city values(11,'上饶市',15)
--16山东省(2005年,辖:17个地级市;49个市辖区、31个县级市、60个县。)
insert into city values(1,'济南市',16)
insert into city values(2,'青岛市',16)
insert into city values(3,'淄博市',16)
insert into city values(4,'枣庄市',16)
insert into city values(5,'东营市',16)
insert into city values(6,'烟台市',16)
insert into city values(7,'潍坊市',16)
insert into city values(8,'济宁市',16)
insert into city values(9,'泰安市',16)
insert into city values(10,'威海市',16)
insert into city values(11,'日照市',16)
insert into city values(12,'莱芜市',16)
insert into city values(13,'临沂市',16)
insert into city values(14,'德州市',16)
insert into city values(15,'聊城市',16)
insert into city values(16,'滨州市',16)
insert into city values(17,'菏泽市',16)
--17河南省(2005年辖:17个地级市;50个市辖区、21个县级市、88个县。)
insert into city values(1,'郑州市',17)
insert into city values(2,'开封市',17)
insert into city values(3,'洛阳市',17)
insert into city values(4,'平顶山市',17)
insert into city values(5,'安阳市',17)
insert into city values(6,'鹤壁市',17)
insert into city values(7,'新乡市',17)
insert into city values(8,'焦作市',17)
insert into city values(9,'濮阳市',17)
insert into city values(10,'许昌市',17)
insert into city values(11,'漯河市',17)
insert into city values(12,'三门峡市',17)
insert into city values(13,'南阳市',17)
insert into city values(14,'商丘市',17)
insert into city values(15,'信阳市',17)
insert into city values(16,'周口市',17)
insert into city values(17,'驻马店市',17)
insert into city values(18,'济源市',17)
--18湖北省(截至2005年12月31日,全省辖13个地级单位(12个地级市、1个自治州);102县级单位(38个市辖区、24个县级市、37个县、2个自治县、1个林区),共有1220个乡级单位(277个街道、733个镇、210个乡)。)
insert into city values(1,'武汉市',18)
insert into city values(2,'黄石市',18)
insert into city values(3,'十堰市',18)
insert into city values(4,'荆州市',18)
insert into city values(5,'宜昌市',18)
insert into city values(6,'襄樊市',18)
insert into city values(7,'鄂州市',18)
insert into city values(8,'荆门市',18)
insert into city values(9,'孝感市',18)
insert into city values(10,'黄冈市',18)
insert into city values(11,'咸宁市',18)
insert into city values(12,'随州市',18)
insert into city values(13,'仙桃市',18)
insert into city values(14,'天门市',18)
insert into city values(15,'潜江市',18)
insert into city values(16,'神农架林区',18)
insert into city values(17,'恩施土家族苗族自治州',18)
--19湖南省(2005年辖:13个地级市、1个自治州;34个市辖区、16个县级市、65个县、7个自治县。)
insert into city values(1,'长沙市',19)
insert into city values(2,'株洲市',19)
insert into city values(3,'湘潭市',19)
insert into city values(4,'衡阳市',19)
insert into city values(5,'邵阳市',19)
insert into city values(6,'岳阳市',19)
insert into city values(7,'常德市',19)
insert into city values(8,'张家界市',19)
insert into city values(9,'益阳市',19)
insert into city values(10,'郴州市',19)
insert into city values(11,'永州市',19)
insert into city values(12,'怀化市',19)
insert into city values(13,'娄底市',19)
insert into city values(14,'湘西土家族苗族自治州',19)
--20广东省(截至2005年12月31日,广东省辖:21个地级市,54个市辖区、23个县级市、41个县、3个自治县,429个街道办事处、1145个镇、4个乡、7个民族乡。)
insert into city values(1,'广州市',20)
insert into city values(2,'深圳市',20)
insert into city values(3,'珠海市',20)
insert into city values(4,'汕头市',20)
insert into city values(5,'韶关市',20)
insert into city values(6,'佛山市',20)
insert into city values(7,'江门市',20)
insert into city values(8,'湛江市',20)
insert into city values(9,'茂名市',20)
insert into city values(10,'肇庆市',20)
insert into city values(11,'惠州市',20)
insert into city values(12,'梅州市',20)
insert into city values(13,'汕尾市',20)
insert into city values(14,'河源市',20)
insert into city values(15,'阳江市',20)
insert into city values(16,'清远市',20)
insert into city values(17,'东莞市',20)
insert into city values(18,'中山市',20)
insert into city values(19,'潮州市',20)
insert into city values(20,'揭阳市',20)
insert into city values(21,'云浮市',20)
--21甘肃省(2006年辖:12个地级市、2个自治州;17个市辖区、4个县级市、58个县、7个自治县。)
insert into city values(1,'兰州市',21)
insert into city values(2,'金昌市',21)
insert into city values(3,'白银市',21)
insert into city values(4,'天水市',21)
insert into city values(5,'嘉峪关市',21)
insert into city values(6,'武威市',21)
insert into city values(7,'张掖市',21)
insert into city values(8,'平凉市',21)
insert into city values(9,'酒泉市',21)
insert into city values(10,'庆阳市',21)
insert into city values(11,'定西市',21)
insert into city values(12,'陇南市',21)
insert into city values(13,'临夏回族自治州',21)
insert into city values(14,'甘南藏族自治州',21)
--22四川省(2006年辖:18个地级市、3个自治州;43个市辖区、14个县级市、120个县、4个自治县。)
insert into city values(1,'成都市',22)
insert into city values(2,'自贡市',22)
insert into city values(3,'攀枝花市',22)
insert into city values(4,'泸州市',22)
insert into city values(5,'德阳市',22)
insert into city values(6,'绵阳市',22)
insert into city values(7,'广元市',22)
insert into city values(8,'遂宁市',22)
insert into city values(9,'内江市',22)
insert into city values(10,'乐山市',22)
insert into city values(11,'南充市',22)
insert into city values(12,'眉山市',22)
insert into city values(13,'宜宾市',22)
insert into city values(14,'广安市',22)
insert into city values(15,'达州市',22)
insert into city values(16,'雅安市',22)
insert into city values(17,'巴中市',22)
insert into city values(18,'资阳市',22)
insert into city values(19,'阿坝藏族羌族自治州',22)
insert into city values(20,'甘孜藏族自治州',22)
insert into city values(21,'凉山彝族自治州',22)

--24贵州省(2006年辖:4个地级市、2个地区、3个自治州;10个市辖区、9个县级市、56个县、11个自治县、2个特区。)
insert into city values(1,'贵阳市',24)
insert into city values(2,'六盘水市',24)
insert into city values(3,'遵义市',24)
insert into city values(4,'安顺市',24)
insert into city values(5,'铜仁地区',24)
insert into city values(6,'毕节地区',24)
insert into city values(7,'黔西南布依族苗族自治州',24)
insert into city values(8,'黔东南苗族侗族自治州',24)
insert into city values(9,'黔南布依族苗族自治州',24)
--25海南省(2003-2005年 全省有2个地级市,6个县级市,4个县,6个民族自治县,4个市辖区,1个办事处(西南中沙群岛办事处,县级)。)
insert into city values(1,'海口市',25)
insert into city values(2,'三亚市',25)
insert into city values(3,'五指山市',25)
insert into city values(4,'琼海市',25)
insert into city values(5,'儋州市',25)
insert into city values(6,'文昌市',25)
insert into city values(7,'万宁市',25)
insert into city values(8,'东方市',25)
insert into city values(9,'澄迈县',25)
insert into city values(10,'定安县',25)
insert into city values(11,'屯昌县',25)
insert into city values(12,'临高县',25)
insert into city values(13,'白沙黎族自治县',25)
insert into city values(14,'昌江黎族自治县',25)
insert into city values(15,'乐东黎族自治县',25)
insert into city values(16,'陵水黎族自治县',25)
insert into city values(17,'保亭黎族苗族自治县',25)
insert into city values(18,'琼中黎族苗族自治县',25)
--26云南省(2006年辖:8个地级市、8个自治州;12个市辖区、9个县级市、79个县、29个自治县。)
insert into city values(1,'昆明市',26)
insert into city values(2,'曲靖市',26)
insert into city values(3,'玉溪市',26)
insert into city values(4,'保山市',26)
insert into city values(5,'昭通市',26)
insert into city values(6,'丽江市',26)
insert into city values(7,'思茅市',26)
insert into city values(8,'临沧市',26)
insert into city values(9,'文山壮族苗族自治州',26)
insert into city values(10,'红河哈尼族彝族自治州',26)
insert into city values(11,'西双版纳傣族自治州',26)
insert into city values(12,'楚雄彝族自治州',26)
insert into city values(13,'大理白族自治州',26)
insert into city values(14,'德宏傣族景颇族自治州',26)
insert into city values(15,'怒江傈傈族自治州',26)
insert into city values(16,'迪庆藏族自治州',26)
--27青海省(2006年辖:1个地级市、1个地区、6个自治州;4个市辖区、2个县级市、30个县、7个自治县。)
insert into city values(1,'西宁市',27)
insert into city values(2,'海东地区',27)
insert into city values(3,'海北藏族自治州',27)
insert into city values(4,'黄南藏族自治州',27)
insert into city values(5,'海南藏族自治州',27)
insert into city values(6,'果洛藏族自治州',27)
insert into city values(7,'玉树藏族自治州',27)
insert into city values(8,'海西蒙古族藏族自治州',27)
--28陕西省(2006年辖:10个地级市;24个市辖区、3个县级市、80个县。)
insert into city values(1,'西安市',28)
insert into city values(2,'铜川市',28)
insert into city values(3,'宝鸡市',28)
insert into city values(4,'咸阳市',28)
insert into city values(5,'渭南市',28)
insert into city values(6,'延安市',28)
insert into city values(7,'汉中市',28)
insert into city values(8,'榆林市',28)
insert into city values(9,'安康市',28)
insert into city values(10,'商洛市',28)
--29广西壮族自治区(2005年辖:14个地级市;34个市辖区、7个县级市、56个县、12个自治县。)
insert into city values(1,'南宁市',29)
insert into city values(2,'柳州市',29)
insert into city values(3,'桂林市',29)
insert into city values(4,'梧州市',29)
insert into city values(5,'北海市',29)
insert into city values(6,'防城港市',29)
insert into city values(7,'钦州市',29)
insert into city values(8,'贵港市',29)
insert into city values(9,'玉林市',29)
insert into city values(10,'百色市',29)
insert into city values(11,'贺州市',29)
insert into city values(12,'河池市',29)
insert into city values(13,'来宾市',29)
insert into city values(14,'崇左市',29)
--30西藏自治区(2005年辖:1个地级市、6个地区;1个市辖区、1个县级市、71个县。)
insert into city values(1,'拉萨市',30)
insert into city values(2,'那曲地区',30)
insert into city values(3,'昌都地区',30)
insert into city values(4,'山南地区',30)
insert into city values(5,'日喀则地区',30)
insert into city values(6,'阿里地区',30)
insert into city values(7,'林芝地区',30)
--31宁夏回族自治区
insert into city values(1,'银川市',31)
insert into city values(2,'石嘴山市',31)
insert into city values(3,'吴忠市',31)
insert into city values(4,'固原市',31)
insert into city values(5,'中卫市',31)
--32新疆维吾尔自治区(2005年辖:2个地级市、7个地区、5个自治州;11个市辖区、20个县级市、62个县、6个自治县)
insert into city values(1,'乌鲁木齐市',32)
insert into city values(2,'克拉玛依市',32)
insert into city values(3,'石河子市 ',32)
insert into city values(4,'阿拉尔市',32)
insert into city values(5,'图木舒克市',32)
insert into city values(6,'五家渠市',32)
insert into city values(7,'吐鲁番市',32)
insert into city values(8,'阿克苏市',32)
insert into city values(9,'喀什市',32)
insert into city values(10,'哈密市',32)
insert into city values(11,'和田市',32)
insert into city values(12,'阿图什市',32)
insert into city values(13,'库尔勒市',32)
insert into city values(14,'昌吉市 ',32)
insert into city values(15,'阜康市',32)
insert into city values(16,'米泉市',32)
insert into city values(17,'博乐市',32)
insert into city values(18,'伊宁市',32)
insert into city values(19,'奎屯市',32)
insert into city values(20,'塔城市',32)
insert into city values(21,'乌苏市',32)
insert into city values(22,'阿勒泰市',32)
--33内蒙古自治区(2006年,辖:9个地级市、3个盟;21个市辖区、11个县级市、17个县、49个旗、3个自治旗。)
insert into city values(1,'呼和浩特市',33)
insert into city values(2,'包头市',33)
insert into city values(3,'乌海市',33)
insert into city values(4,'赤峰市',33)
insert into city values(5,'通辽市',33)
insert into city values(6,'鄂尔多斯市',33)
insert into city values(7,'呼伦贝尔市',33)
insert into city values(8,'巴彦淖尔市',33)
insert into city values(9,'乌兰察布市',33)
insert into city values(10,'锡林郭勒盟',33)
insert into city values(11,'兴安盟',33)
insert into city values(12,'阿拉善盟',33)
--34澳门特别行政区
insert into city values(1,'澳门特别行政区',34)
--35香港特别行政区
insert into city values(1,'香港特别行政区',35)
----------------------------------------------------------------------------------------------------------------------------------------
--查询语句
select * from promary
select * from city创建DB.cs实现代码重用
using System;
using System.Data.SqlClient;
namespace DBPromary
...{
public class DB
...{
public DB()
...{
//
// TODO: 在此处添加构造函数逻辑
//
}
public static SqlConnection createConnection()
...{
SqlConnection con=new SqlConnection("server='local';database='DBPromary';user id='**';password='***'");
return con;
}
}
}

posted @ 2010-12-17 21:21 羽落无声 阅读(398) 评论(1)  编辑

原文地址:http://www.cnblogs.com/huomm/archive/2007/12/05/984102.html

前些日子作一些数据项目的时候 在ADO.NET 中处理ExecuteNonQuery()方法时,总是通过判断其返回值是否大于0来判断操作时候成功 。但是实际上并不是这样的,好在处理的数据操作多时 修改, 插入, 删除,否则的话问题就有点打了,都是些基础的知识,但是很重要个人觉得有必要记下来。

ExecuteNonQuery()方法主要用户更新数据,通常它使用Update,Insert,Delete语句来操作数据库,其方法返回值意义:对于Update,Insert,Delete 语句 执行成功是返回值为该命令所影响的行数,如果影响的行数为0时返回的值为0,如果数据操作回滚得话返回值为-1,对于这种更新操作 用我们平时所用的是否大于0的判断操作应该没有问题而且比较好,但是对于其他的操作如对数据库结构的操作,如果操作成功时返回的却是-1,这种情况跟我们平时的思维方式有点差距所以应该好好的注意了,例如对数据库共添加一个数据表的Create操作,当创建数据表成功时返回-1,如果操作失败的话(如数据表已经存在)往往会发生异常,所以执行这种操作时最好用try--catch--语句来容错。

例如用ExecuteNonQuery()方法执行create操作



SqlConnection conn = new SqlConnection("Data Source=.;Initial Catalog=PSDB;Integrated Security=SSPI");

string str = "CREATE TABLE aaa ( " +
"[ID] [int] IDENTITY (1, 1) NOT NULL , " +
"[BasicID] [int] NULL ," +
"[AdoptedName] [varchar] (50) COLLATE Chinese_PRC_CI_AS NULL ," +
"[AdoptedSex] [char] (2) COLLATE Chinese_PRC_CI_AS NULL ," +
"[AdoptBirthday] [smalldatetime] NULL ," +
"[AdoptedType] [varchar] (100) COLLATE Chinese_PRC_CI_AS NULL ," +
"[ApprTime] [smalldatetime] NULL ," +
"[Remark] [varchar] (500) COLLATE Chinese_PRC_CI_AS NULL " +
") ON [PRIMARY] ";

SqlCommand comm = new SqlCommand(str, conn);
int i = 10;
try
{
conn.Open();
i = comm.ExecuteNonQuery();
conn.Close();
}
catch (Exception ex)
{
Response.Write(ex.Message);
}

Response.Write(i.ToString());

如果执行成功的话 返回的值为-1,如果数据表已经存在的话返回异常:数据库中已存在名为 'aaa' 的对象。

posted @ 2010-12-17 21:21 羽落无声 阅读(222) 评论(0)  编辑

少了一些图片,我懒得拷了,大家还是去源地址看吧

http://www.codeproject.com/KB/cs/idispose.aspx

极力推荐!!!!

Introduction


This is yet another article on the use of the interface class IDisposable. Essentially, the code that you are going to see here is no different than the code on MSDN or these two excellent articles:


Garbage Collection in .NET by Chris Maunder:
http://www.codeproject.com/managedcpp/garbage_collection.asp

General Guidelines for C# Class Implementation by Eddie Velasquez:
http://www.codeproject.com/csharp/csharpclassimp.asp

What's different is that this article illustrates the functional aspects of:
the destructor
the Dispose method
memory allocation
garbage collection issues

In other words, there's lots of articles showing how to implement IDisposable, but very few demonstration of why to implement IDisposable.
How To Implement IDisposable

The salient features of the code below are:
Implement the Dispose method of the IDisposable interface
Only Dispose of resources once
The implementing class requires a destructor
Prevent the GC from disposing of resources if they've already been manually disposed
Track whether the GC is disposing of the object rather than the application specifically requesting that the object is disposed. This concerns how resources that the object manages are handled.

And here's a flowchart:



Note two things:
If Dispose is used on an object, it prevents the destructor from being called and manually releases managed and unmanaged resources.
If the destructor is called, it only releases unmanaged resources. Any managed resources will be de-referenced and also (possibly) collected.

There are two problem with this, which I'll come back to later:
Using Dispose does not prevent you from continuing to interact with the object!
A managed resource may be disposed of, yet still referenced somewhere in the code!

Here's an example class implementing IDisposable, which manages a Image object and has been instrumented to illustrate the workings of the class.
Collapse
public class ClassBeingTested : IDisposable
{
private bool disposed=false;
private Image img=null;

public Image Image
{
get {return img;}
}

// the constructor

public ClassBeingTested()
{
Trace.WriteLine("ClassBeingTested: Constructor");
}

// the destructor

~ClassBeingTested()
{
Trace.WriteLine("ClassBeingTested: Destructor");
// call Dispose with false. Since we're in the

// destructor call, the managed resources will be

// disposed of anyways.

Dispose(false);
}

public void Dispose()
{
Trace.WriteLine("ClassBeingTested: Dispose");
// dispose of the managed and unmanaged resources

Dispose(true);

// tell the GC that the Finalize process no longer needs

// to be run for this object.

GC.SuppressFinalize(this);
}

protected virtual void Dispose(bool disposeManagedResources)
{
// process only if mananged and unmanaged resources have

// not been disposed of.

if (!this.disposed)
{
Trace.WriteLine("ClassBeingTested: Resources not disposed");
if (disposeManagedResources)
{
Trace.WriteLine("ClassBeingTested: Disposing managed resources");
// dispose managed resources

if (img != null)
{
img.Dispose();
img=null;
}
}
// dispose unmanaged resources

Trace.WriteLine("ClassBeingTested: Disposing unmanaged resouces");
disposed=true;
}
else
{
Trace.WriteLine("ClassBeingTested: Resources already disposed");
}
}

// loading an image

public void LoadImage(string file)
{
Trace.WriteLine("ClassBeingTested: LoadImage");
img=Image.FromFile(file);
}
}
Why Implement IDisposable?

Let's put this class into a simple GUI driven test fixture that looks like this:



and we'll use two simple tools to monitor what's going:
DebugView to watch the execution: http://www.sysinternals.com/ntw2k/freeware/debugview.shtml
the Task Manager's Performance view for memory utilization.

The test is very simple, involving loading a 3MB image file several times, with the option to dispose of the object manually:
Collapse
private void Create(int n)
{
for (int i=0; i<n; i++)
{
ClassBeingTested cbt=new ClassBeingTested();
cbt.LoadImage("fish.jpg");
if (ckDisposeOption.Checked)
{
cbt.Dispose();
}
}
}

The unsuspecting fish, by the way, is a Unicorn Fish, taken at Sea World, San Diego California:



Observe what happens when I create 10 fish:



Ten fish took up 140MB, (which is odd, because the fish is only a 3MB file, so you'd think no more than 30MB would be consumed, but we won't get into THAT).

Furthermore, observe that the destructors on the objects were never invoked:



If we create 25 fish, followed by another 10, notice what happens to the time it takes to haul in the fish, as a result of heavy disk swapping:



This is now taking two seconds on average to load one fish! And did the GC start collecting garbage any time soon? No! Conversely, if we dispose of the class as soon as we're done using it (which in our test case is immediately), there is no memory hogging and no performance degradation. So, to put it mildly, it is very important to consider whether or not a class needs to implement the IDispose interface, and whether or not to manually dispose of objects.
Behind The Scenes

Let's create one fish and then force the GC to collect it. The resulting trace looks like:



Observe that in this case, the destructor was called and managed resources were not manually disposed.

Now, instead, let's create one fish with the dispose flag checked, then force the GC to collect it. The resulting trace looks like:



Observe in this case, that both managed and unmanaged resources are disposed, AND that the destructor call is suppressed.
Problems

As described above, even though an object is disposed, there is nothing preventing you from continuing to use the object and any references you may have acquired to objects that it manages, as demonstrated by this code:
Collapse
private void btnRefTest_Click(object sender, System.EventArgs e)
{
ClassBeingTested cbt=new ClassBeingTested();
cbt.LoadImage("fish.jpg");
Image img=cbt.Image;
cbt.Dispose();
Trace.WriteLine("Image size=("+img.Width.ToString()+", "+img.Height.ToString()+")");
}

Of course, the result is:


Solutions

Ideally, one would want to assert or throw an exception when:
Dispose is called and managed objects are still referenced elsewhere
methods and accessors are called after the object has been disposed

Unfortunately (as far as I know) there is no way to access the reference count on an object, so it becomes somewhat difficult to determine if a managed object is still being referenced elsewhere. Besides require that the application "release" references, the best solution is to simply not allow another object to gain a reference to an internally managed object. In other words, the code:
Collapse
public Image Image
{
get {return img;}
}

should simply not be allowed in a "managing" class. Instead, the managing class should implement all the necessary support functions that other classes require, implementing a facade to the managed object. Using this approach, the application can throw an exception if the disposed flag is true--indicating that the object is still being accessed after it has technically been disposed of.
Conclusion - Unit Testing

The reason I went through this rigmarole is that I wanted to demonstrate the inadequacies of unit testing. For example, let us assume that the test class I described above does not implement IDisposable. Here we have an excellent example of how a single test on a class and its functions will succeed wonderfully, giving the illusion that all is well with a program that uses the class. But all is not well, because the class does not provide a means for the application to dispose of its managed resources, ultimately causing the entire computer system to bog down in fragmented memory and disk swapping.

This does not mean that unit testing is bad. It does however illustrate that it is far from a complete picture, and unit testing applications such as NUnit could use considerable growth in order to help the programmer automate more complex forms of unit testing.

And that, my friends, is going to be the topic of the next article.
Downloading The Demonstration Project

I have intentionally left out the "fish.jpg", being 3MB in size. Please edit the code and use your own JPG if you wish to play with the code.
License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here
About the Author
Marc Clifton


Architect
Interacx
United States

Member
posted @ 2010-12-17 21:21 羽落无声 阅读(29) 评论(0) 编辑

在初学时,我们使用SqlConnection来初始化连接数据库,这里要注意,SqlConnection继承自IDispose,这就要求我们在使用SqlConnection后调用Dispose对他进行清理。

当然除了SqlConnection,以后我们所用的command,read等都要如此

这里有两种方法

方法一:

try{

SqlConnection conn = new SqlConnection(@"Data Source=.\SQLEXPRESS;AttachDBFilename=|DataDirectory|\Database1.mdf;Integrated Security=True;User Instance=True;");

}

finally

{

conn.close();

conn.Dispose();

}

方法二:

IDispose是清理该对象的一个接口,该接口只有一个方法Dispose,继承该接口主要用于using语句,比如:
class A:IDispose
{
public override void Dispose()
{
......
}
......
}
using(A a = new A())
{
......
}
using结束时会自动释放对象a,也就是自动调用A的Dispose方法,所以A必须继承IDispose才能使用using语句,using结束时,会做如下动作:
IDispose d = a as IDispose;
d.Dispose();

using在退出作用域后会自动调用Dispose,而继承自Idispose类的内部,会自行判断有没有调用close,如果没有则先close再dispose

我们可以通过.net Reflector来反编译看一下

protected override void Dispose(bool disposing)
{    if (disposing)
{        this._userConnectionOptions = null;
this._poolGroup = null;
this.Close();    }    
this.DisposeMe(disposing);
base.Dispose(disposing);
} 

所以,这就很简单了。

using(SqlConnection conn = new SqlConnection(@"Data Source=.\SQLEXPRESS;AttachDBFilename=|DataDirectory|\Database1.mdf;Integrated Security=True;User Instance=True;"))

{

conn.open();

}

posted @ 2010-12-17 21:21 羽落无声 阅读(117) 评论(0)  编辑

开始学习ADO.NET了,但是遇到了一些小问题,花了好久才解决。

Q:在使用ASP.NET 2.0 + SQL2005 + aspnetdb(MemberShip等功能)时出现这个问题:“由于启动用户实例的进程时出错,导致无法生成 SQL Server的用户实例。该连接将关闭。”,其英文版本的相同问题的错误信息是:“Failed to generate a user instance of SQL Server due to a failure in starting the process for the user instance. The connection will be closed.”


A:这是一个缓存的冲突

删除C:\Documents and Settings\[USERNAME]\Local Settings\Application Data\Microsoft\Microsoft SQL Server Data\SQLEXPRESS目录即可,[USERNAME]是Windows用户名,比如说Administrator




posted @ 2010-12-17 21:21 羽落无声 阅读(17) 评论(0)  编辑

在用ADO.NET时有时会遇到查询不到数据的状况,即使列属性设置为VARCHAR(N),也不能有效避免前后空格,所以要对查询数据做一定处理

去空格函数



1、LTRIM() 把字符串头部的空格去掉。

2、RTRIM() 把字符串尾部的空格去掉。



执行:


select ' 3k'
select LTRIM(' 3k') as LTRIM --把字符串头部的空格去掉
select '9C '
select RTRIM('9C ') as RTRIM --把字符串尾部的空格去掉


&apos;代表的是单引号 得到结果如下:






posted @ 2010-12-17 21:21 羽落无声 阅读(74) 评论(0)  编辑
摘自:http://livenzhao.spaces.live.com/blog/cns!6E368BE9F6DDD872!595.entry
·PL/SQL Developer使用技巧


1、PL/SQL Developer记住登陆密码

在使用PL/SQL Developer时,为了工作方便希望PL/SQL Developer记住登录Oracle的用户名和密码;

设置方法:PL/SQL Developer 7.1.2->tools->Preferences->Oracle->Logon History , "Store history"是默认勾选的,勾上"Store with password"即可,重新登录在输入一次密码则记住了。
2、执行单条SQL语句

在使用PL/SQL Developer的SQL Window时,按F8键,PL/SQL Developer默认是执行该窗口的所有SQL语句,需要设置为鼠标所在的那条SQL语句,即执行当前SQL语句;

设置方法:PL/SQL Developer 7.1.2-->tools->Preferences-->Window types ,勾上"AutoSelect Statement" 即可。
3、格式化SQL语句

在使用PL/SQL Developer的SQL Window时,有时候输入的SQL语句太长或太乱,希望能用比较通用的写法格式话一下,这样看起来会好看些,也好分析;

使用方法:选中需要格式化的SQL语句,然后点击工具栏的PL/SQL beautifier按钮即可.
4、查看执行计划

在使用PL/SQL Developer的SQL Window时,有时候输入的SQL语句执行的效率,分析下表结构,如何可以提高查询的效率,可以通过查看Oracle提供的执行计划;

使用方法:选中需要分析的SQL语句,然后点击工具栏的Explain plan按钮(即执行计划),或者直接按F5即可。
5、调试存储过程

在使用PL/SQL Developer操作Oracle时,有时候调用某些存储过程,或者调试存储过程;

调用存储过程的方法:首先,在PL/SQL Developer左边的Browser中选择Procedures,查找需要调用的存储过程;然后,选中调试的存储过程,点击右键,选择Test,在弹出来的Test scrīpt窗口中,对于定义为in类型的参数,需要给该参数的Value输入值;最后点击上面的条数按钮:Start debugger或者按F9;最后点击:RUN 或者Ctrl+R


·Oracle学习手册:新手常见错误小集



没有人会否认ORACLE是全球最有影响的数据库产品之一;不过好的东西似乎总不是那么好用(初看起来如此),甚至有些无情--总会给layman们一个个无情的错误号。下面是我个人的总结,条条有用,希望能给初学者一点启示。

  关于"好的东西似乎总不是那么好用(初看起来如此)"的一个笑话:在参加 IBM DB2 512、513培训前,在校园网上下载到了安装程序,不过任凭我们几个同学研究个半天,也不知哪个文件是安装文件,竟没有安装成功。最后,一致认为:看来这个培训真是太有必要了!事后,才知道--我们下载的是4linux的!

  [以8.1.6为例]:
  1、ORA-12541:TNS:没有监听器

  原因:没有启动监听器或者监听器损坏。如果是前者,使用命令net start OracleOraHome81TNSListener(名字可能有出入)即可;如果是后者,则使用"Net8 Configuration Assistant"工具向导之"监听程序配置"增加一个监听器即可(基本不用写任何信息,一路OK。在添加之前可能需要把所有的监听器先删除!)
  2、ORA-12500:TNS:监听程序无法启动专用服务器进程

  或

  ORA-12560:TNS:协议适配器错误

  原因:ORACLE的数据库服务没有启动。使用命令net start ORACLESERVICEORADB(ORADB为数据库名字)即可。如果仍没有解决,请继续向下看。
  3、如果数据库服务启动失败,则很有可能是其注册表项值损坏,最好的做法是以下两步:

  1)ORADIM -DELETE -SID oradb 删除数据库服务项

  2)ORADIM -NEW -SID oradb 新增数据库服务项

  注:这个过程中如果出错,就重启计算机!
  4、ORA-12154:TNS:能解析服务名

  原因:ORACLE的网络服务名没有正确配置。请使用"Net8 Configuration Assistant"工具向导之"本地网络服务名配置"配置TNS即可。如果仍没有解决,请继续向下看。
  5、ORA-1034 :TNS:ORACLE不可用

  原因:ORACLE的数据库服务正确启动,但是数据库没有打开!

  使用命令:

  1)svrmgrl 启动服务管理器

  2)connect internal 以internal身份登陆

  3)startup 打开数据库
  6、ORA-12560:TNS:协议适配器错误(顽固性的)

  原因:未知。

  解决:必杀技--打开"Windows任务管理器",杀死ORACLE.exe及ORADIM.exe进程,书写自己的ora_startup.bat,执行之!

  PS:

  1、我的ora_startup.bat:

  net start OracleOraHome81TNSListener

  net start ORACLESERVICEORADB

  svrmgrl 一般情况下不用,不过有时少不了它的,具体步骤见第5步。

  2、我的ora_shutdown.bat:

  net stop OracleOraHome81TNSListener

  net stop ORACLESERVICEORADB

  3、ORACLE相关服务名请参见"管理工具"之"服务"中以ORACLE开头的服务名。


·Oracle 10g绿色客户端 plus PL/SQL Developer-搭建方便的Oracle客户端使用环境



整个一个暑假都在做基于Oracle的一个数据处理程序。但是一直没有找到合适的人工访问实验室的数据库的方便的方法。

最酷的时候我的做法是自己写个程序用JDBC连接数据库自己扒下想要的表格……

后来发现实验室里边有很多机器是装过Oracle客户端的,但是ms都是当时实验室搭建数据库时用正版的安装光盘装的,我对这样臃肿的客户端有一种生理上的恐惧,于是还是用原始的方法进行自己的开发。

直到有一天,看到Oracle的官方网站上边有10g的绿色版的简易客户端……

http://www.oracle.com/technology/tech/oci/instantclient/index.html

Oracle的官方网站下载软件是要帐户的,这个申请一个就是了,本人没有网上的空间存放相关的软件,即使有也没有官网上的可靠和持久,所以就只给一个链接了。

http://www.allroundautomations.nl/plsqldev.html

国内也有下载http://download.enet.com.cn/speed/toftp.php?fname=232142006032101免去大家的麻烦!


PL/SQL Developer是一个开发与数据库相关工程的软件,ms是Free的,不大了解,只不过看到很多开发Oracle相关数据库的人都在用,我一般只用来当作与数据库服务器交互用的Client界面……,最多的时候主要是开一个窗口敲SQL语句,(杀鸡用牛刀了……)

下边是安装的过程,由于是免安装的,所以要自己配置一些环境变量和文件,比较麻烦……

首先将下载的Oracle客户端的压缩包解压到一个路径,在本机上解压到了E:\OracleClient下边,所以,实际上Oracle客户端的路径是E:\OracleClient\instantclient_10_2

然后进入instantclient_10_2文件夹,新建一个network文件夹,并在network文件夹下新建admin文件夹,在admin文件夹中新建名为tnsnames.ora文件,这个文件是用来配置连接远程数据库的登录信息的(客户端软件都会从这个相对路径下的文件中获取连接数据库的信息),内容如下:

databasename =

(DESCRIPTION =

(ADDRESS_LIST =

(ADDRESS = (PROTOCOL = TCP)(HOST = ip address)(PORT = 1521))

)

(CONNECT_DATA =

(SERVICE_NAME = database name)

)

)

例如我链接实验室数据库的对应文件内容是:

TCM =

(DESCRIPTION =

(ADDRESS_LIST =

(ADDRESS = (PROTOCOL = TCP)(HOST = *.*.*.*)(PORT = 1521))

)

(CONNECT_DATA =

(SERVICE_NAME = TCM)

)

)

IP我就不写出来了,我所用的数据库名为TCM,so……



然后安装PL/SQL Developer,过程是傻瓜式的。进入PL/SQL后(开始进入时会要求登录数据库,但是现在PL/SQL现在还找不到你的Oracle客户端,所以登录是不会成功的,但是可以进入软件),选择Tools->Preferences,在Oracle Home OCI Library两栏中分别填入Oracle客户端的路径和OCI文件的路径(oci.dll文件直接在instantclient_10_2文件夹下),所以我在这两个选项中填写的内容是"E:\OracleClient\instantclient_10_2"和"E:\OracleClient \instantclient_10_2\oci.dll"。这时再登录就可以登录成功了。如若还不行就重启一下PL/SQL。



绿色版的客户端可能会出现对于中文支持的问题,这主要是因为服务器端指定的字符集和客户端所默认的字符集是不相同的导致的,只要找到服务器端的字符集设置,然后将客户端的字符集设置与服务器端保持一致就好了。修改客户端字符集设置的方法有好几种,可以修改注册表,也可以用环境变量的方法解决。不过我这里介绍的客户端是绿色版的,只是解压到某一个路径而已,所以注册表的方法在这里不是很适用,所以我写了一个启动脚本,在启动PL/SQL之前,先建一个临时环境变量nls_lang,并给变量赋值,再启动软件。(我曾经做过实验,通过建立系统环境变量的方法在这里是行不通的,具体的原因我说不清楚><)



我的脚本plsql.bat的内容如下:



set nls_lang=SIMPLIFIED CHINESE_CHINA.ZHS16GBK

cd "c:\Program Files\PLSQL Developer"

PLSQLDev.exe

其中第二行进入的路径是PL/SQL Developer安装到的路径。



我这里的实际情况是服务器端的字符集设置为SIMPLIFIED CHINESE_CHINA.ZHS16GBK,所以我将这个值赋给nls_lang。通过运行plsql.bat脚本就可以正常的访问服务器数据库了。
posted @ 2010-12-17 21:21 羽落无声 阅读(62) 评论(0)  编辑

本文出自 “赵宏臣主页”博客,请务必保留此出处http://zhcsmx22.blog.51cto.com/287943/113172

1 字符串分割

string url = "[url]http://asdfsfd[/url][*]asdf[*]asdfsdf[*]";
string[] sss = GetString(url,"[*]");
foreach(string str in sss)
{
Response.Write(str.ToString() +" ");
}

private string[] GetString(string str,string cutStr)
{
char[] cutChar = cutStr.ToCharArray();
string[] sArray = str.Split(cutChar);
return sArray;
}

2 字符串截取

public static string GetFirstString(string stringToSub, int length)
{
Regex regex = new Regex("[\u4e00-\u9fa5]+", RegexOptions.Compiled);
char[] stringChar = stringToSub.ToCharArray();
StringBuilder sb = new StringBuilder();
int nLength = 0;
bool isCut=false;
for(int i = 0; i < stringChar.Length; i++)
{
if (regex.IsMatch((stringChar[i]).ToString()))
{
sb.Append(stringChar[i]);
nLength += 2;
}
else
{
sb.Append(stringChar[i]);
nLength = nLength + 1;
}

if (nLength > length)
{
isCut=true;
break;
}
}
if(isCut)
return sb.ToString()+"...";
else
return sb.ToString();
}

3.取子串函数SubString
string tmp2 = tmp1.SubString(0,3);
相当于vb.net中的mid
tring str="abcdefg";
string str1=str.Substring(2,3);//str1="cde"

4.C#中有什么函数可以判断某一字符串中是否存在着某一字符?如:"akkk*kkk"是否有“*”?

string s = "akkk*kkk";
int i = s.IndexOf("*");

if( i != -1) 包含
else 不包含

5.右对齐此实例中的字符,在左边用指定的 Unicode 字符填充以达到指定的总长度。
[C#] public string PadLeft(int, char);
str = "256";
str = str.PadLeft(5,"0"); //str = "00256"

本文出自 “赵宏臣主页”博客,请务必保留此出处http://zhcsmx22.blog.51cto.com/287943/113172

posted @ 2010-12-17 21:21 羽落无声 阅读(216) 评论(0)  编辑

本文来自Lucky Jack的博客园文章《如何去除C#Strings中的空格? 》

http://www.cnblogs.com/yangjie5188


你或许知道你能使用String.Trim方法去除字符串的头和尾的空格,不幸运的是.这个Trim方法不能去除字符串中间的空格.比如:

string text = " My test\nstring\r\n is\t quite long ";
string trim = text.Trim();
这个'trim' 字符串将会是:
"My test\nstring\r\n is\t quite long" (31 characters)
另一个方法是使用 String.Replace 方法, 但是这需要你通过调用多个方法来去除个别空格:
string trim = text.Replace( " ", "" );
trim = trim.Replace( "\r", "" );
trim = trim.Replace( "\n", "" );
trim = trim.Replace( "\t", "" );
这里最好的方法就是使用正则表达式.你能使用Regex.Replace方法,它将所有匹配的替换为指定的字符.在这个例子中,使用正则表达式匹配符"\s",它将匹配任何空格包含在这个字符串里空格, tab字符,换行符和新行(newline).
string trim = Regex.Replace( text, @"\s", "" );
这个'trim' 字符串将会是:
"Myteststringisquitelong" (23 characters)

posted @ 2010-12-17 21:21 羽落无声 阅读(132) 评论(0)  编辑
最近经常看到论坛中许多帖子询问如何使用split来分割字符串,我这里对split做一些简单的总结,希望能够对大家有所帮助。下面介绍几种方法:

第一种方法:打开vs.net新建一个控制台项目。然后在Main()方法下输入下面的程序。

string s="abcdeabcdeabcde";

string[] sArray=s.Split(''c'');

foreach(string i in sArray)

Console.WriteLine(i.ToString());



输出下面的结果:ab

deab

deab

de





我们看到了结果是以一个指定的字符进行的分割。如果我们希望使用多个字符进行分割如c,d,e如何做呢?好,我们使用另一种构造方法:



更改为 string s="abcdeabcdeabcde

string[] sArray1=s.Split(new char[3]{''c'',''d'',''e''});

foreach(string i in sArray1)

Console.WriteLine(i.ToString());



可以输出下面的结果:ab

ab

ab



除了以上的这两种方法以外,第三种方法是使用正则表达式。新建一个控制台项目。然后先添加 using System.Text.RegularExPRessions;
'http://www.knowsky.com
Main() :中更改为

System.Text.RegularExpressions

string content="agcsmallmacsmallgggsmallytx";

string[]resultString=Regex.Split(content,"small",RegexOptions.IgnoreCase)
foreach(string i in resultString)
Console.WriteLine(i.ToString());

输出下面的结果:agc
mac
ggg
ytx
使用正则表达式有什么好处呢? 别着急,后面我们会看到它的独特之处。
下面介绍第4种方法。比如

string str1="我*****是*****一*****个*****教*****师";

如果我希望显示为:我是一个教师, ,如何作呢? 我们可以使用下面代码:





string str1="我*****是*****一*****个*****教*****师;

string[] str2;

str1=str1.Replace("*****","*");

str2=str1.Split(''*'');

foreach(string i in str2)

Console.WriteLine(i.ToString());





这样也可以得到正确结果。但是比如

string str1="我**是*****一*****个*****教*****师";

我希望显示的结果为:我是一个教师。

我如果采用上面的第四种方法来做就会产生下面的错误:我 是一个教师

中间有空格输出,所以输出结果并不是我希望的结果,如何解决呢?这就又回到了正则表达式了(这里可以看到它的功能强大之处),这时可以采用下面的第五种方法:



string str1="我**是*****一*****个*****教*****师";

string[] str2 = System.Text.RegularExpressions.Regex.Split(str1,@"[*]+");

foreach(string i in str2)

Console.WriteLine(i.ToString());



这里通过"[*]+" 巧妙的完成了我们的目标。
posted @ 2010-12-17 21:21 羽落无声 阅读(5) 评论(0)  编辑
如果在为方法声明参数时未使用 ref 或out,则该参数可以具有关联的值。可以在方法中更改该值,但当控制传递回调用过程时,不会保留更改的值。通过使用方法参数关键字,可以更改这种行为。
params

params 关键字可以指定在参数数目可变处采用参数的方法参数。
在方法声明中的 params 关键字之后不允许任何其他参数,并且在方法声明中只允许一个 params 关键字。

示例:

字面意思比较难懂,所以看示例很有用。
// keywords_params.cs

using System;

class App
{
public static void UseParams(params object[] list)
{
for (int i = 0; i < list.Length; i++)
{
Console.WriteLine(list[i]);
}
}

static void Main()
{
// 一般做法是先构造一个对象数组,然后将此数组作为方法的参数
object[] arr = new object[3] { 100, 'a', "keywords" };
UseParams(arr);

// 而使用了params修饰方法参数后,我们可以直接使用一组对象作为参数
// 当然这组参数需要符合调用的方法对参数的要求
UseParams(100, 'a', "keywords");

Console.Read();
}
}
ref

ref 关键字使参数按引用传递。其效果是,当控制权传递回调用方法时,在方法中对参数所做的任何更改都将反映在该变量中。
若要使用 ref 参数,则方法定义和调用方法都必须显式使用 ref 关键字。
传递到 ref 参数的参数必须最先初始化。这与 out 不同,out 的参数在传递之前不需要显式初始化。
属性不是变量,因此不能作为 ref 参数传递。
尽管 ref 和 out 在运行时的处理方式不同,但它们在编译时的处理方式是相同的。因此,如果一个方法采用 ref参数,而另一个方法采用 out参数,则无法重载这两个方法。例如,从编译的角度来看,以下代码中的两个方法是完全相同的。如果尝试这么做,将导致不能编译该代码。
如果一个方法采用 ref 或 out 参数,而另一个方法不采用这两类参数,则可以进行重载。

示例:

按引用传递值类型是有用的,但是 ref对于传递引用类型也是很有用的。这允许被调用的方法修改该引用所引用的对象,因为引用本身是按引用来传递的。
// keywords_ref.cs

using System;

class App
{
public static void UseRef(ref int i)
{
i += 100;
Console.WriteLine("i = {0}", i);
}

static void Main()
{
int i = 10;

// 查看调用方法之前的值
Console.WriteLine("Before the method calling: i = {0}", i);

UseRef(ref i);

// 查看调用方法之后的值
Console.WriteLine("After the method calling: i = {0}", i);
Console.Read();
}
}


out

out 关键字会导致参数通过引用来传递。这与 ref 关键字类似。

与 ref 的不同之处:
ref 要求变量必须在传递之前进行初始化。
尽管作为 out 参数传递的变量不需要在传递之前进行初始化,但需要调用方法以便在方法返回之前赋值。

示例:

与 ref 示例不同的地方只要将 ref 改为 out,然后变量 i 仅需要声明即可。
static void Main()
{
//int i = 10; 改为
int i;
//
}
本篇内容参考MSDN文档。
posted @ 2010-12-17 21:21 羽落无声 阅读(3) 评论(0)  编辑
posted @ 2010-12-17 21:21 羽落无声 阅读(236) 评论(0)  编辑

一、预备知识—程序的内存分配

一个由C/C++编译的程序占用的内存分为以下几个部分

1、栈区(stack)—   由编译器自动分配释放   ,存放函数的参数值,局部变量的值等。其

操作方式类似于数据结构中的栈。

2、堆区(heap)   —   一般由程序员分配释放,   若程序员不释放,程序结束时可能由OS回

收   。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表,呵呵。

3、全局区(静态区)(static)—,全局变量和静态变量的存储是放在一块的,初始化的

全局变量和静态变量在一块区域,  未初始化的全局变量和未初始化的静态变量在相邻的另

一块区域。   -   程序结束后由系统释放。

4、文字常量区   —常量字符串就是放在这里的。  程序结束后由系统释放

5、程序代码区—存放函数体的二进制代码。

 

 

二、例子程序  

这是一个前辈写的,非常详细  

//main.cpp  

int   a   =   0;   全局初始化区  

char  *p1;   全局未初始化区  

main()  

  {  

int  b;  栈  

char  s[]   =   "abc";   栈  

char  *p2;  栈  

char  *p3   =   "123456";   123456\0在常量区,p3在栈上。  

static  int   c   =0;   全局(静态)初始化区  

  p1   =   (char   *)malloc(10);  

  p2   =   (char   *)malloc(20);  

分配得来得10和20字节的区域就在堆区。  

strcpy(p1,  "123456");  123456\0放在常量区,编译器可能会将它与p3所指向的"123456"

优化成一个地方。  

  }  

 

 

二、堆和栈的理论知识  

2.1申请方式  

stack:  

由系统自动分配。   例如,声明在函数中一个局部变量  int  b;  系统自动在栈中为b开辟空

间   

heap:  

需要程序员自己申请,并指明大小,在c中malloc函数  

如p1   =   (char   *)malloc(10);  

在C++中用new运算符  

如p2   =   new   char[10];  

但是注意p1、p2本身是在栈中的。  

 

 

2.2  

申请后系统的响应  

栈:只要栈的剩余空间大于所申请空间,系统将为程序提供内存,否则将报异常提示栈溢

出。  

堆:首先应该知道操作系统有一个记录空闲内存地址的链表,当系统收到程序的申请时,

会遍历该链表,寻找第一个空间大于所申请空间的堆结点,然后将该结点从空闲结点链表

中删除,并将该结点的空间分配给程序,另外,对于大多数系统,会在这块内存空间中的

首地址处记录本次分配的大小,这样,代码中的delete语句才能正确的释放本内存空间。

另外,由于找到的堆结点的大小不一定正好等于申请的大小,系统会自动的将多余的那部

分重新放入空闲链表中。  

 

2.3申请大小的限制  

栈:在Windows下,栈是向低地址扩展的数据结构,是一块连续的内存的区域。这句话的意

思是栈顶的地址和栈的最大容量是系统预先规定好的,在WINDOWS下,栈的大小是2M(也有

的说是1M,总之是一个编译时就确定的常数),如果申请的空间超过栈的剩余空间时,将

提示overflow。因此,能从栈获得的空间较小。  

堆:堆是向高地址扩展的数据结构,是不连续的内存区域。这是由于系统是用链表来存储

的空闲内存地址的,自然是不连续的,而链表的遍历方向是由低地址向高地址。堆的大小

受限于计算机系统中有效的虚拟内存。由此可见,堆获得的空间比较灵活,也比较大。  

 

 

 

2.4申请效率的比较:  

栈由系统自动分配,速度较快。但程序员是无法控制的。  

堆是由new分配的内存,一般速度比较慢,而且容易产生内存碎片,不过用起来最方便.  

另外,在WINDOWS下,最好的方式是用VirtualAlloc分配内存,他不是在堆,也不是在栈是

直接在进程的地址空间中保留一块内存,虽然用起来最不方便。但是速度快,也最灵活。

   

 

2.5堆和栈中的存储内容  

栈:   在函数调用时,第一个进栈的是主函数中后的下一条指令(函数调用语句的下一条可

执行语句)的地址,然后是函数的各个参数,在大多数的C编译器中,参数是由右往左入栈

的,然后是函数中的局部变量。注意静态变量是不入栈的。  

当本次函数调用结束后,局部变量先出栈,然后是参数,最后栈顶指针指向最开始存的地

址,也就是主函数中的下一条指令,程序由该点继续运行。  

堆:一般是在堆的头部用一个字节存放堆的大小。堆中的具体内容由程序员安排。  

 

2.6存取效率的比较  

 

char  s1[]  =  "aaaaaaaaaaaaaaa";  

char  *s2   =  "bbbbbbbbbbbbbbbbb";  

aaaaaaaaaaa是在运行时刻赋值的;  

而bbbbbbbbbbb是在编译时就确定的;  

但是,在以后的存取中,在栈上的数组比指针所指向的字符串(例如堆)快。  

比如:  

#include  

void  main()  

  {  

char  a   =   1;  

char  c[]   =   "1234567890";  

char  *p  ="1234567890";  

  a   =   c[1];  

  a   =   p[1];  

return;  

  }  

对应的汇编代码  

10:   a   =   c[1];  

00401067  8A   4D   F1   mov   cl,byte   ptr   [ebp-0Fh]  

0040106A  88   4D   FC   mov   byte   ptr   [ebp-4],cl  

11:   a   =   p[1];  

0040106D  8B   55   EC   mov   edx,dword   ptr   [ebp-14h]  

00401070  8A   42   01   mov   al,byte   ptr   [edx+1]  

00401073  88   45   FC   mov   byte   ptr   [ebp-4],al  

第一种在读取时直接就把字符串中的元素读到寄存器cl中,而第二种则要先把指针值读到

edx中,再根据edx读取字符,显然慢了。  

 

 

2.7小结:  

堆和栈的区别可以用如下的比喻来看出:  

使用栈就象我们去饭馆里吃饭,只管点菜(发出申请)、付钱、和吃(使用),吃饱了就

走,不必理会切菜、洗菜等准备工作和洗碗、刷锅等扫尾工作,他的好处是快捷,但是自

由度小。  

使用堆就象是自己动手做喜欢吃的菜肴,比较麻烦,但是比较符合自己的口味,而且自由

度大。   (经典!)

posted @ 2010-12-17 21:21 羽落无声 阅读(12) 评论(0)  编辑
最近收集整理了一些输入是否为数字的几种方法
方法一:

static bool IsNumeric(string str)
{
if (str==null || str.Length==0)
return false;
foreach(char c in str)
{
if (!Char.IsNumber(c))
{
return false;
}
}
return true;
}



方法二:


private bool IsNumeric(string s)
{
char ch0 = '0';
char ch9 = '9';
for(int i=0; i < s.Length; i++)
{
if ((s[i] < ch0 || s[i] > ch9))
{
this.lblwarning.Text="此处应输入整数且非负!";
return false;
}
}
return true;
}


方法三:


static bool IsNumeric (string str)
{

System.Text.RegularExpressions.Regex reg1
= new System.Text.RegularExpressions.Regex(@"^[-]?\d+[.]?\d*$");
return reg1.IsMatch(str);
}



方法四:(可扩展)


public static bool IsConvert(string Expression,Type DataType)

{

switch(DataType.Name)

{

case "Double":

try

{

Double.Parse(Expression);

return true;

}

catch

{

return false;

}

case "DateTime":

try

{

DateTime.Parse(Expression);

return true;

}

catch

{

return false;

}

default:

return true;

}

}
posted @ 2010-12-17 21:21 羽落无声 阅读(16) 评论(0)  编辑
原文链接:http://blog.sina.com.cn/s/blog_6c0f946a0100mufo.html
posted @ 2010-12-17 21:21 羽落无声 阅读(67) 评论(0)  编辑
posted @ 2010-12-17 21:21 羽落无声 阅读(805) 评论(0)  编辑
原文链接:http://blog.sina.com.cn/s/blog_6c0f946a0100mo7x.html
posted @ 2010-12-17 21:21 羽落无声 阅读(13) 评论(0)  编辑
原文链接:http://blog.sina.com.cn/s/blog_6c0f946a0100mo73.html
posted @ 2010-12-17 21:21 羽落无声 阅读(13) 评论(0)  编辑
正则表达式用于字符串处理、表单验证等场合,实用高效。现将一些常用的表达式收集于此,以备不时之需。

匹配中文字符的正则表达式:[\u4e00-\u9fa5]
评注:匹配中文还真是个头疼的事,有了这个表达式就好办了

匹配双字节字符(包括汉字在内):[^\x00-\xff]
评注:可以用来计算字符串的长度(一个双字节字符长度计2,ASCII字符计1)

匹配空白行的正则表达式:\n\s*\r
评注:可以用来删除空白行

匹配HTML标记的正则表达式:<(\S*?)[^>]*>.*?</\1>|<.*? />
评注:网上流传的版本太糟糕,上面这个也仅仅能匹配部分,对于复杂的嵌套标记依旧无能为力

匹配首尾空白字符的正则表达式:^\s*|\s*$
评注:可以用来删除行首行尾的空白字符(包括空格、制表符、换页符等等),非常有用的表达式

匹配Email地址的正则表达式:\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*
评注:表单验证时很实用

匹配网址URL的正则表达式:[a-zA-z]+://[^\s]*
评注:网上流传的版本功能很有限,上面这个基本可以满足需求

匹配帐号是否合法(字母开头,允许5-16字节,允许字母数字下划线):^[a-zA-Z][a-zA-Z0-9_]{4,15}$
评注:表单验证时很实用

匹配国内电话号码:\d{3}-\d{8}|\d{4}-\d{7}
评注:匹配形式如 0511-4405222 或 021-87888822

匹配腾讯QQ号:[1-9][0-9]{4,}
评注:腾讯QQ号从10000开始

匹配中国邮政编码:[1-9]\d{5}(?!\d)
评注:中国邮政编码为6位数字

匹配身份证:\d{15}|\d{18}
评注:中国的身份证为15位或18位

匹配ip地址:\d+\.\d+\.\d+\.\d+
评注:提取ip地址时有用

匹配特定数字:
^[1-9]\d*$    //匹配正整数
^-[1-9]\d*$   //匹配负整数
^-?[1-9]\d*$   //匹配整数
^[1-9]\d*|0$  //匹配非负整数(正整数 + 0)
^-[1-9]\d*|0$   //匹配非正整数(负整数 + 0)
^[1-9]\d*\.\d*|0\.\d*[1-9]\d*$   //匹配正浮点数
^-([1-9]\d*\.\d*|0\.\d*[1-9]\d*)$  //匹配负浮点数
^-?([1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0)$  //匹配浮点数
^[1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0$   //匹配非负浮点数(正浮点数 + 0)
^(-([1-9]\d*\.\d*|0\.\d*[1-9]\d*))|0?\.0+|0$  //匹配非正浮点数(负浮点数 +0)
评注:处理大量数据时有用,具体应用时注意修正

匹配特定字符串:
^[A-Za-z]+$  //匹配由26个英文字母组成的字符串
^[A-Z]+$  //匹配由26个英文字母的大写组成的字符串
^[a-z]+$  //匹配由26个英文字母的小写组成的字符串
^[A-Za-z0-9]+$  //匹配由数字和26个英文字母组成的字符串
^\w+$  //匹配由数字、26个英文字母或者下划线组成的字符串
评注:最基本也是最常用的一些表达式

原载地址:http://lifesinger.3322.org/myblog/?p=185

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值