通过空测试则抛出NullPointerException

本文关键字:NullPointerException 测试 | 更新日期: 2023-09-27 18:08:19

我在下面的代码中检查Null,即使通过了虚假路径,Null测试也通过了。但是,当我返回工作簿时,抛出NullPointerException。我怎么能检查一个NullPointerReference在这种情况下?当我在调试时检查workBook变量时,它被设置为某些东西,我相信这一定是它通过Null检查的原因。

public static ExcelWorkbook OpenExcelWorkSheet(string file_path)
{
    string EXCEL_FILE_EXTENSION = ".xlsx",
    full_path = file_path + EXCEL_FILE_EXTENSION;
    var excelFile = new FileInfo(full_path);
    using (var package = new ExcelPackage(excelFile))
    {
        ExcelWorkbook workBook = package.Workbook;
        if (workBook.Equals(null))
        {
            throw new Exception("ERROR!!!");
        }
        else { Console.Write("not null"); }
        return workBook;
    }
}

通过空测试则抛出NullPointerException

查看ExcelPackage的源代码,Workbook属性永远不能返回null。如果它的getter发现它的内部字段是null,它将创建一个新的Workbook:

public ExcelWorkbook Workbook
{
    get
    {
        if (_workbook == null)
        {
            var nsm = CreateDefaultNSM();
            _workbook = new ExcelWorkbook(this, nsm);
            _workbook.GetExternalReferences();
            _workbook.GetDefinedNames();
        }
        return (_workbook);
    }
}

知道了这一点,我想你可以安全地把支票拿走。

此外,正如其他人所指出的,您确实需要小心如何使用using语句。当一个ExcelPackage被释放时,它的Workbook也会被释放(您可以在我链接的源代码中看到这种情况)。这可能就是为什么您看到从方法返回的null工作簿,但在using语句中看不到的原因。在关闭using}后不久,它变成了null

如果你有一个用来包装EPPlus功能的类,那么你应该确保它:

  1. 只实例化ExcelPackage一次,并保留对它的引用;当你这样做的时候不要使用using语句
  2. 让你的其他方法在需要的时候访问这个ExcelPackage引用;不要传阅或重新打开包装
  3. 实现IDisposable,然后在包装器处理ExcelPackage对象时正确处理。

这里有一个例子*:

public class YourWrapper : IDisposable
{
    private bool disposed;
    public YourWrapper()
    {
    }
    public YourWrapper(string path)
    {
        OpenExcelPackage(path);
    }
    public void OpenExcelPackage(string path)
    {
        Package = new ExcelPackage(path);
    }
    public ExcelPackage Package { get; private set; }
    protected virtual void Dispose(bool disposing)
    {
        if (!this.disposed)
        {
            if (disposing)
            {
                if (Package != null)
                {
                    Package.Dispose();
                    Package = null;
                }
            }
        }
        this.disposed = true;
    }
    ~YourWrapper()
    {
        Dispose(false);
    }
    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }
}

现在,在实例化包装器时使用using:

using (var wrapper = new YourWrapper())
{
    // Do everything related to manipulating the Excel file here
}

一切都会收拾得很好。


*请更改类/方法的名称为更合适的名称;这只是为了说明。

相关文章:
  • 没有找到相关文章