07-单例模式与异常处理

2021-04-16  本文已影响0人  D丝学编程

一、单例模式

单例模式主要是为了确保只有单个对象被创建,主要解决一个类的对象频繁地创建与销毁,

我们通过如下示例来了解单例模式的作用,以及实现方案:


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
{
    //
}
上一篇下一篇

猜你喜欢

热点阅读