c#4.0-如何在c#中进行异常处理

本文关键字:异常处理 c#4 | 更新日期: 2023-09-27 17:58:10

我有一个小控制台应用程序,它将在ExcelDataReader的帮助下读取excel数据。控制台应用程序的代码:

class Program
{
    static void Main(string[] args)
    {
        SomeData data = new SomeData(@"C:'SC.xlsx", "somedata_2014");
        IEnumerable<SomeType> someTypes = someData.GetData();
        Console.ReadLine();
    }
}

请不要担心变量的命名;这是为一家公司准备的,我不想使用任何与公司相关的东西。下一个是SomeData类:

public class SomeData
{
    private string path;
    private string worksheetName;
    public SomeData(string path, string worksheetName)
    {
        this.path = path;
        this.worksheetName = worksheetName;
    }
    public IEnumerable<SomeType> GetData(bool isFirstRowAsColumnNames = true)
    {
        var excelData = new ExcelData(path);
        try
        {
            var ad = excelData.GetData(worksheetName, isFirstRowAsColumnNames);
            return ad.Select(dataRow => new SomeType()
            {
                Gemeente = dataRow["LivingPlace"].ToString(),
                Geslacht = dataRow["Outdoors"].ToString(),
                Woonplaats = dataRow["WellHellYesOrNo"].ToString()
            }).ToList();
        }
        catch (FileNotFoundException ex)
        {
            throw;
        }
        catch (ArgumentException ex)
        {
            throw;
        }
    }
}

最后,ExcelData类比SomeData类低一个级别:

public class ExcelData
{
    private string path;
    public ExcelData(string path)
    {
        this.path = path;
    }
    private IExcelDataReader GetExcelDataReader()
    {
        try
        {
            using (FileStream fileStream = File.Open(path, FileMode.Open, FileAccess.Read))
            {
                IExcelDataReader dataReader = null;
                if (path.EndsWith(".xls"))
                {
                    dataReader = ExcelReaderFactory.CreateBinaryReader(fileStream);
                }
                if (path.EndsWith(".xlsx"))
                {
                    dataReader = ExcelReaderFactory.CreateOpenXmlReader(fileStream);
                }
                return dataReader;
            }
        }
        catch (FileNotFoundException ex)
        {
            Console.WriteLine(ex);
            throw;
        }
    }
    public IEnumerable<DataRow> GetData(string sheet, bool isFirstRowAsColumnNames = true)
    {
        var reader = GetExcelDataReader();
        reader.IsFirstRowAsColumnNames = isFirstRowAsColumnNames;
        var workSheet = reader.AsDataSet().Tables[sheet];
        var rows = from DataRow row in workSheet.Rows select row;
        return rows;
    }
}

我想做的是,当打开excel文件时出现问题时,我希望它抛出一个异常,并且我希望它出现气泡,这样我就可以在最高级别上写出它。

SomeData类的GetData方法也是如此;当我想读取某一列的数据,但出现问题时,我希望它抛出一个冒泡的异常,这样我就可以再次在顶层写出它。

我只是在寻找最好的方法。

c#4.0-如何在c#中进行异常处理

默认情况下出现异常"bubble";不做任何事情就重新抛出异常是没有意义的,这只是浪费了代码和CPU。事实上,这几乎就是异常的全部操作方式-无论发生什么,无论发生在哪里,都会由第一个准备好处理它的人来处理。所以你只需要在你真正准备好处理的时候使用try { ... } catch (WhateverException ex) { ... }

任何根本没有处理的异常都会杀死你的应用程序(尽管要注意,像Winforms这样的某些框架会给你一个选择,例如尝试并继续——不过,总的来说,你应该自己处理所有这些,这只是最后的安全网)。

在"较高"级别捕获异常的最佳方法是在"较低"级别根本不捕获它们。它们会自动冒出来,你可以在任何你认为合适的时候抓住/处理它们。

没有理由使用这样的代码,因为您所做的唯一事情就是重新抛出异常。

catch (FileNotFoundException ex)
{
    throw;
}
catch (ArgumentException ex)
{
    throw;
}

像这样的代码很好,因为你在重新抛出异常之前要对它进行处理。例如,你可能会在重新抛出它之前记录一个异常,这样调用方法也可以捕捉并处理它(比如向用户显示错误)。

catch (FileNotFoundException ex)
{
    Console.WriteLine(ex);
    throw;
}

如果您可以在较低级别处理和修复问题,请在那里捕获异常并修复问题。如果你想让所有的异常都冒泡到顶部,在那里你可以提醒用户,然后删除所有的try/catch块,只在Main:中捕获

try
{
    SomeData data = new SomeData(@"C:'SC.xlsx", "somedata_2014");
    IEnumerable<SomeType> someTypes = someData.GetData();
}
catch (Exception ex)
{
    Console.WriteLine(ex.Message);
}

只是不要在每个方法中都捕获异常-只有当你能对它做一些事情时,你才应该捕获异常(处理它(即不重新抛出它),添加一些重要的上下文信息,或者如果它对日志记录很重要)

所以你想的方法是好的,要么让它弹出到gui,要么,如果你能处理/添加信息,你也可以在数据类中捕捉它,但我不会在我使用的每个类中捕捉到它

当然,这个决定还取决于你的哪些部件被其他应用程序/组件重用。

还有一件事是异常链接:低级别异常(例如"除以零")被重新评估为新的异常,如"数据异常"。。取决于您的应用程序模型

我想您要做的是将错误气泡上升到顶层,这样您就可以看到它在多个级别上被抛出的位置。我说得对吗?无论如何,您不需要catch/sthrow语句,而是定义一个方法像一样可丢弃

public IEnumerable<SomeType> GetData(bool isFirstRowAsColumnNames = true) throws Exception

在这种情况下,如果GetData中发生错误,它将向上冒泡您还可以定义应该抛出什么类型的表达式,或者定义可以抛出的多个异常