一、单例模式
单例模式主要是为了确保只有单个对象被创建,主要解决一个类的对象频繁地创建与销毁,
我们通过如下示例来了解单例模式的作用,以及实现方案:
0029.PNG
如上图,我们只要点击一次"普通模式"的菜单,即会创建一个新的窗体对象。
0030.PNG
而我们如果使用单例模式,即点击"单例模式"菜单,当唯一对象不存在的时候,会创建一个窗体,但是当窗体已经存在的时候,将不会创建新的窗体。
主要实现方案即步骤如下:
(1)在项目中创建窗体"FrmMain",并且设置窗体IsMdiContainer属性为true表示该窗体为MDI父窗体。
(2)拖入MenuStrip控件,并给该控件创建两个一级菜单"普通模式","单例模式"。
(3)在项目中创建两个窗体FrmCommon和FrmSingle分别用于点击"普通模式"菜单和"单例模式"菜单弹出的窗体,并且在两个窗体中使用lable写入必要的文本用作区分。
(4)在FrmSingle窗体中声明一个自己本身的静态实例,然后编写方法用于实现控制此静态实例的创建。
private static FrmSingle frm; //单例模式
//单例模式创建窗体
public static FrmSingle CreateFrom()
{
if (frm == null || frm.IsDisposed)
{
//当实例不存在或实例被释放时
frm = new FrmSingle();
}
return frm;
}
(5)分别编写"普通模式","单例模式"两个菜单的响应代码,实现普通的打开窗体和单例模式打开窗体的功能。
#region 普通模式
private void toolStripButton1_Click(object sender, EventArgs e)
{
FrmComman frm = new FrmComman();
frm.MdiParent = this;
frm.Show();
}
#endregion
#region 单例模式
private void toolStripButton2_Click(object sender, EventArgs e)
{
FrmSingle frm = FrmSingle.CreateFrom();
frm.MdiParent = this;
frm.Show();
}
#endregion
注意:此实例只是将单例模式应用在打开窗体这样一个场景上,单例模式的应用场景不仅如此,只要是在程序中,你想控制某一个类只能有单个对象被创建,都可以使用单例模式。
二、异常处理
任何完美的应用程序和技术高明的程序员,都不能保证程序绝对不出差错,所以我们需要异常处理。
通俗而言,程序中的错误可以分为以下3类:
(1)编译错误
在程序编译时产生的错误,通常由错误的语法或使用的资源不存在等原因引起。产生编译错误时程序无法运行,编
译错误可以通过集成开发环境VS发现。
(2)逻辑错误
逻辑错误,不影响程序的正常运行,但会导致实际运行结果与预期结果不一致。通常是算法出现了错误,可以通过
调试程序,对比期望值和实际值发现。
(3)异常
在程序运行过程中,干扰程序正常运行时产生的错误称为异常。异常是无法避免的,但是能够预计。为了使应用程
序出现异常时不至于崩溃终止,必须对可能出现异常的代码进行异常处理。
(1)异常处理的简单结构
try
{
//可能出现异常的代码
}
catch(Exception ex)
{
//捕获到异常,进行异常处理的代码
}
try
{
//可能出现异常的代码
}
catch(Exception ex)
{
//捕获到异常,进行异常处理的代码
}
finally
{
//释放资源的代码
}
异常处理的流程说明:
--try块中包含可能出现异常的代码,在执行过程中若出现异常,程序不会继续执行try块中位于异常代码之后的语句,而是直接跳转至catch块中进行异常处理。
--catch块中包含进行异常处理的代码,只有当try块中出现异常时,catch块才会被执行。
--finally块中包含释放资源的代码。无论是否发生异常,finally块均会被执行。
示例(此程序会捕捉到下标越界的异常,进入到catch语句块):
try
{
string[] arr = new string[5];
arr[5] = "Jack";
}
catch (Exception ex) //发生异常进入到catch
{
MessageBox.Show("程序出现异常:" + ex.Message);
}
finally //不管是否发生异常都会进入finally,也可以没有finally
{
//
}
(2)多重Catch捕获不同类型的异常
try
{
// 引起异常的语句
}
catch( ExceptionName e1 )
{
// 错误处理代码
}
catch( ExceptionName e2 )
{
// 错误处理代码
}
catch( ExceptionName eN )
{
// 错误处理代码
}
finally
{
// 要执行的语句
}
try语句块如果发生异常,会在多个catch中寻找相应的异常类型,进入到相应catch代码块中。
常见异常类型(所有的异常类型都继承自Exception基类):
异常类 | 描述 |
---|---|
System.IO.IOException | 处理 I/O 错误。 |
System.IndexOutOfRangeException | 处理当方法指向超出范围的数组索引时生成的错误。 |
System.ArrayTypeMismatchException | 处理当数组类型不匹配时生成的错误。 |
System.NullReferenceException | 处理当依从一个空对象时生成的错误。 |
System.DivideByZeroException | 处理当除以零时生成的错误。 |
System.InvalidCastException | 处理在类型转换期间生成的错误。 |
System.OutOfMemoryException | 处理空闲内存不足生成的错误。 |
System.StackOverflowException | 处理栈溢出生成的错误。 |
System.Data.SqlClient.SqlException | SQL操作异常。 |
示例:
//通过注释的方式分别产生三种异常,查看会进入哪一个catch处理
try
{
//模拟下标越界异常
string[] arr = new string[5];
arr[5] = "Jack";
//模拟数据库连接异常
string connStr = "server=.;database=DBTEST;uid=sa;pwd=123456";
SqlConnection conn = new SqlConnection(connStr);
conn.Open();
//模拟其他异常
int a = 10;
int b = 0;
int temp = a / b;
}
catch (IndexOutOfRangeException ex) //下标越界异常
{
string strErr = "程序出现异常:" + ex.Message + "\n";
strErr += "请联系项目经理:13558785456";
MessageBox.Show(strErr);
}
catch (System.Data.SqlClient.SqlException ex) //sql操作异常
{
string strErr = "数据库连接异常:" + ex.Message + "\n";
strErr += "请联系数据库管理员:13558785456";
MessageBox.Show(strErr);
}
catch (Exception ex) //此处为Exception基类,上面所有异常类型都无法匹配的时候会进入到这里处理
{
MessageBox.Show("程序出现异常:" + ex.Message);
}
finally //不管是否发生异常都会进入finally,也可以没有finally
{
//
}
网友评论