开放的编程资料库

当前位置:我爱分享网 > C#教程 > 正文

C#异常

在本文中,我们展示了如何在C#中处理异常。

异常表示应用程序执行期间发生的错误。

在我们的应用程序执行期间,许多事情可能会出错。磁盘可能已满,我们无法保存文件。当我们的应用程序尝试连接到某个站点时,Internet连接可能会中断。这些错误可能会导致包括应用程序崩溃在内的问题。程序员有责任处理可以预见的错误。

trycatchfinally关键字用于处理异常。

Exception是所有异常的基类。错误由抛出的异常报告。抛出异常后,由应用程序或默认异常处理程序处理。异常包含有关错误的信息。

在应用程序开发期间和开发完成后会抛出不同类型的异常。开发人员会收到包含大量技术细节的异常,而用户只会收到简短、基本的信息性消息。

C#捕获异常

catch关键字用于捕获抛出的异常。

int x = 100;
int y = 0;
int z;

try
{
    z = x / y;
}
catch (ArithmeticException e)
{
    Console.WriteLine("An exception occurred");
    Console.WriteLine(e.Message);
}

在上面的程序中,我们有意将一个数字除以零。这会导致错误。请注意,这是一个演示异常如何工作的学术示例。实际上,被错误除法是一个程序错误,通过确保分母不为零来解决。

try
{
    z = x / y;
}

容易出错的语句放在try块中。

catch (ArithmeticException e)
{
    Console.WriteLine("An exception occurred");
    Console.WriteLine(e.Message);
}

异常类型跟在catch关键字之后。在我们的例子中,我们有一个ArithmeticException。此异常会因算术、转换或转换操作中的错误而抛出。catch关键字后面的语句在发生错误时执行。当异常发生时,会创建一个异常对象。我们从这个对象中获取Message属性并将其打印到控制台。

$ dotnet run
An exception occurred
Attempted to divide by zero.

C#未捕获的异常

当前上下文中任何未捕获的异常都会传播到更高的上下文,并寻找合适的catch块来处理它。如果找不到任何合适的catch块,.NET运行时的默认机制将终止整个程序的执行。

int x = 100;
int y = 0;

int z = x / y;

Console.WriteLine(z);

在这个程序中,我们除以零。没有自定义异常处理。

$ dotnet run
Unhandled exception. System.DivideByZeroException: Attempted to divide by zero.
...

C#编译器给出上述错误信息。

C#IO异常

发生I/O错误时抛出IOException。在下面的示例中,我们读取文件的内容。

var fs = new FileStream("langs.txt", FileMode.OpenOrCreate);

try
{
    var sr = new StreamReader(fs);
    string? line;

    while ((line = sr.ReadLine()) != null)
    {
        Console.WriteLine(line);
    }

}
catch (IOException e)
{
    Console.WriteLine("IO Error");
    Console.WriteLine(e.Message);
}
finally
{
    Console.WriteLine("Inside finally block");

    if (fs != null)
    {
        fs.Close();
    }
}

总是执行finally关键字后面的语句。它通常用于清理任务,例如关闭文件或清除缓冲区。

} 
catch (IOException e)
{
    Console.WriteLine("IO Error");
    Console.WriteLine(e.Message);
}

在这种情况下,我们捕获特定的IOException异常。

} 
finally
{
    Console.WriteLine("Inside finally block");

    if (fs != null)
    {
        fs.Close();
    }
}

这些行保证文件处理程序已关闭。

$ cat langs.txt
C#
Java
Python
Ruby
PHP
JavaScript

这些是langs.txt文件的内容。

$ dotnet run
C#
Java
Python
Ruby
PHP
JavaScript
Inside finally block

C#多个异常

我们经常需要处理多个异常。

int x;
int y;
double z;

try
{
    Console.Write("Enter first number: ");
    x = Convert.ToInt32(Console.ReadLine());

    Console.Write("Enter second number: ");
    y = Convert.ToInt32(Console.ReadLine());

    z = x / y;
    Console.WriteLine("Result: {0:N} / {1:N} = {2:N}", x, y, z);
}
catch (DivideByZeroException e)
{
    Console.WriteLine("Cannot divide by zero");
    Console.WriteLine(e.Message);

}
catch (FormatException e)
{
    Console.WriteLine("Wrong format of number.");
    Console.WriteLine(e.Message);
}

在这个例子中,我们捕获了各种异常。请注意,更具体的异常应该在通用异常之前。我们从控制台读取两个数字,并检查零除法错误和错误的数字格式。

$ dotnet run
Enter first number: we
Wrong format of number.
Input string was not in a correct format.

C#自定义异常

自定义异常是派生自System.Exception类的用户定义的异常类。

int x = 340004;
const int LIMIT = 333;

try
{
    if (x > LIMIT)
    {
        throw new BigValueException("Exceeded the maximum value");
    }
}
catch (BigValueException e)
{
    Console.WriteLine(e.Message);
}

class BigValueException : Exception
{
    public BigValueException(string msg) : base(msg) { }
}

我们假设我们遇到了无法处理大数字的情况。

class BigValueException : Exception

我们有一个BigValueException类。此类派生自内置的Exception类。

const int LIMIT = 333;

我们的程序认为大于这个常量的数字是“大”的。

public BigValueException(string msg) : base(msg) {}

在构造器内部,我们调用父级的构造器。我们将消息传递给父母。

if (x > LIMIT)
{
    throw new BigValueException("Exceeded the maximum value");
}

如果值大于限制,我们将抛出自定义异常。我们给异常一条消息“超出最大值”。

} 
catch (BigValueException e)
{
    Console.WriteLine(e.Message);
}

我们捕获异常并将其消息打印到控制台。

$ dotnet run
Exceeded the maximum value

在本文中,我们使用C#处理异常。

列出所有C#教程。

未经允许不得转载:我爱分享网 » C#异常

感觉很棒!可以赞赏支持我哟~

赞(0) 打赏