【问题标题】:C# interop - validate object existsC# 互操作 - 验证对象是否存在
【发布时间】:2009-12-10 18:23:30
【问题描述】:

我想在我的应用程序中使用 COM 对象。
如何确保对象已在机器中注册?

我找到的唯一解决方案(也是 on SO)是在初始化周围使用 try-catch 块:

try {
    Foo.Bar COM_oObject = new Foo.Bar();
} catch (Exception ee) {
    // Something went wrong during init of COM object
}

我可以用其他方式吗?
我觉得通过预期和报告错误来处理错误是错误的,我宁愿知道我会失败并从一开始就避免它。

【问题讨论】:

    标签: c# validation com interop


    【解决方案1】:

    您正在以正确的方式使用异常处理:从您知道如何恢复的特定情况中优雅地失败。

    在这种情况下使用 try-catch 没有问题,但您至少可以更具体地捕获:ComException。

    【讨论】:

    • +1 用于捕获特定异常,尤其是对有据可查且稳定的 API 的单行调用。
    • 那么你的意思是在没有安装对象的情况下没有办法(你知道)避免异常?
    【解决方案2】:

    “我觉得通过期待并报告错误来处理错误是错误的”

    这不正是try-catch的目的吗?顺便说一句,当发生非常糟糕的事情时会发生异常,并且由于您所指的 COM 对象未注册是一件非常糟糕的事情,因此,异常是完美的解决方案。而且您无法以任何其他方式处理异常。

    我认为这是正确的做法。

    【讨论】:

    【解决方案3】:

    如果您知道组件的 ProgId。你可以试试这个技巧

    comType = Type.GetTypeFromProgID(progID,true/*throw on error*/);
    

    【讨论】:

      【解决方案4】:

      如果您经常这样做并希望有一个非异常抛出等效项,请尝试:

      public static class Catching<TException> where TException : Exception
      {
          public static bool Try<T>(Func<T> func, out T result)
          {
              try
              {
                  result = func();
                  return true;
              }
              catch (TException x) 
              {
                  // log exception message (with call stacks 
                  // and all InnerExceptions)
              }
      
              result = default(T);
              return false;
          }
      
          public static T Try<T>(Func<T> func, T defaultValue)
          {
              T result;
              if (Try(func, out result))
                  return result;
      
              return defaultValue;
          }
      }
      

      所以现在你可以这样做了:

      Foo.Bar newObj;
      if (!Catching<ComException>.Try(() => new Foo.Bar(), out newObj))
      {
          // didn't work.
      }
      

      或者,如果您有一个默认对象存储在 defaultMyInterface 中,如果没有更好的方法,您将使用它来实现接口:

      IMyInterface i = Catching<ComException>.Try(() => new Foo.Bar() as IMyInterface,
                                                  defaultMyInterface);
      

      您也可以在完全不同的情况下这样做:

      int queueSize = Catching<MyParsingException>
          .Try(() => Parse(optionStr, "QueueSize"), 5);
      

      如果Parse 抛出MyParsingExceptionqueueSize 将默认为5,否则使用来自Parse 的返回值(或任何其他异常将正常传播,这通常是您想要的意外异常)。

      这有助于避免打断代码流,并集中您的日志记录策略。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多