【问题标题】:Why does this Using() give me an error?为什么这个 Using() 会给我一个错误?
【发布时间】:2011-08-25 13:53:11
【问题描述】:

我正在尝试打开一个(实际上是数百个)excel 文件。我打开应用程序,但想在我打开的每个工作簿周围使用 Using() 功能。为什么会导致错误?

using (Excel.Workbook wbXL = appXL.Workbooks.Open(_sourceFullPath, Type.Missing, Excel.XlFileAccess.xlReadOnly))
{
    //stuff with wbXL
}

using 得到红色下划线并显示“'Microsoft.Office.Interop.excel.Workbook':在 using 语句中使用的类型必须隐式转换为 'System.IDisposable'。

如何做到这一点?

【问题讨论】:

    标签: c# excel interop using


    【解决方案1】:

    正如它所说的——你只能将using与实现IDisposable的类一起使用,这样编译器就知道在终结时调用哪个函数——yourclass.Dispose()。 Excel 互操作类不实现这一点。

    所以你有两个选择:

    1. 为实现 IDispose 的 Excel.Workbook 编写您自己的包装类,并公开对象本身以调用方法,或者也包装这些方法,例如

      public class DisposableWorkbook : IDisposable
      {
          private Excel.Workbook _workbook = null;
      
          public DisposableWorkbook(Excel.Application appXL, String path,
                                    NotSureOfType otherArgument,
                                    Excel.XlFileAccess access)
          {
              _workbook = appXL.Workbooks.Open(path, otherArgument, access);
          }
      
          public Excel.Workbook Workbook
          {
              get { return _workbook; }
          }
      
          public void Dispose()
          {
              if (workbook != null)
              {
                  workbook.Close(Excel.XlSaveAction.xlDoNotSaveChanges,
                                 workbookToClose);
                  workbook = null;
              }
          }
      }
      
      using (DisposableWorkbook dwbXL = new DisposableWorkbook(appXL,
                _sourceFullPath, Type.Missing, Excel.XlFileAccess.xlReadOnly))
      {
           Excel.Workbook wbXL = dwbXL.Workbook;
           // stuff with wbXL
      }
      
    2. 自己实现using,例如

      Excel.Workbook wbXL = null;
      try
      {
          wbxl = appXL.Workbooks.Open(_sourceFullPath, Type.Missing,
                                      Excel.XlFileAccess.xlReadOnly);
          //stuff with wbXL
      }
      finally
      {
          if (wbxl != null) wbxl.Close();
      }
      

    【讨论】:

    • 因此,当我完成 wbXL 后,我会致电 wbXL.Close(Excel.XlSaveAction.xlDoNotSaveChanges, workbookToClose);。这对 GC 来说足够了吗? using 语句不会“更好”吗?
    • @Brad using 语句无论如何都会编译成 try-finally,所以它几乎是一样的。
    • 哦,好吧,这并不像我预期的那么花哨。凉爽的!非常感谢!
    • using 语句包含一个 try-finally ,因此即使出现异常它也会关闭 - 我认为仅此而已,我认为它不会强制 GC 否。如果有更好的方法来清理 System.Runtime.Interop 中某处的对象(例如强制释放 COM 对象),那么您也可以调用它,当然,但我自己不知道。
    • 确定一件事!现在我从一个 csActiveFile 类中访问所有这些东西(打开 excel,关闭它,与 excel 交互)。我从一个表单中调用那个类和那些方法。这就是包装类的意思吗?
    【解决方案2】:

    using 语句中的任何项都必须实现IDisposable 接口。我手头没有文档,但我猜Excel.Workbook 没有实现这个接口。

    【讨论】:

      【解决方案3】:

      using Statement (C# Reference):

      提供方便的语法,确保正确使用 IDisposable 对象。

      Excel.Workbook 没有实现IDisposable,所以你不能使用using..

      【讨论】:

        【解决方案4】:

        你不能让它工作。

        using 块用于从实现IDisposable 接口的对象中尽可能快且安全地释放资源。

        Excel.Workbook 没有实现 IDisposable,因此您不能将其声明为在 using 块中使用。

        【讨论】:

          【解决方案5】:
          Businessmanger emb = new Businessmanger();
                  try
                  {
          
          
                      TempData["deparmentList"] = Deplist;
                      return PartialView("create");
                  }
                  catch (Exception)
                  {
          
          
                      throw;
                  }
                  finally {
                      //object dispose here
                                      ((IDisposable)emb).Dispose();
                  }
          

          【讨论】:

            猜你喜欢
            • 2013-11-14
            • 1970-01-01
            • 1970-01-01
            • 2021-08-10
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2022-01-05
            • 2014-08-31
            相关资源
            最近更新 更多