2

这是我的问题的 MVCE。

我有这个方法使用 MSScriptControl 来动态评估一些公式。

public void DoCalculate()
{
    try
    {
        var evaluator = new Evaluator();
        IScriptControl ctrl = new ScriptControl();
        ctrl.Language = "JavaScript";
        ctrl.AddObject("Evaluator", evaluator, false);
        var calcFunction = "Number(Evaluator.Divide(4,0))";
        double rs = ctrl.Eval(calcFunction);
    }
    catch (CustomException cex)
    {
        // Handle CustomException.
    }
    catch (Exception ex)
    {
        // Handle general Exception.
    }
}

这是 Evaluator 类。

public class Evaluator
{
    public double Divide(int a, int b)
    {
        if (b == 0)
        {
            throw new CustomException("Cannot divide by zero");
        }
        else
        {
            return a / b;
        }
    }

    public void TestThrow()
    {
        throw new CustomException("This is a test");
    }
}

这是 CustomException 类:

using System;

namespace Library
{
    public class CustomException : Exception
    {
        public CustomException()
            : base()
        {
        }

        public CustomException(string message)
            : base(message)
        {
        }
    }
}

我预计在这种情况下会抛出 CustomException,并输入第一个 catch 子句。但是,我得到了一个通用消息Exception(我使用 验证了异常类型GetType().Name),消息是“不能被零除”。

不过,我确实在 Evaluator 类中收到了以下错误:

XXX.dll 中出现“Library.CustomException”类型的异常,但未在用户代码中处理

如果我像这样修改我的 DoCalculate() ,那么我可以很好地捕获一个 CustomException :

public void DoCalculate()
{
    try
    {
        var evaluator = new Evaluator();
        evaluator.TestThrow();
    }
    catch (CustomException cex)
    {
        // Handle CustomException.
    }
    catch (Exception ex)
    {
        // Handle general Exception.
    }
}

这是否意味着不可能从 Eval 函数内部定义和抛出我自己的异常?

我正在使用 .NET 4.6.2 和 Interop.MSScriptControl 1.0.0.0

4

1 回答 1

2

这是此链接中给出的答案的摘要

COM 方法通过返回HRESULTs;来报告错误。.NET 方法通过抛出异常来报告它们。运行时处理两者之间的转换。.NET Framework 中的每个异常类都映射到一个 HRESULT。因此,为了引发适当的异常,让我提出以下建议。

var evaluator = new Evaluator();
IScriptControl ctrl = new MSScriptControl.ScriptControl { Language = "VBScript" };
ctrl.AddObject("Evaluator", new Evaluator(), true);
const string calcFunction = "Evaluator.Divide(4,0)";
try {
    double rs = ctrl.Eval(calcFunction);
}
catch (DivideByZeroException ex) {//Actual DivideByZeroException from .Net
    //How can you divide by zero?!?!
}
catch (Exception ex) {
    //STUFF
}

public class Evaluator {

    public double Divide(int a, int b) {
        if (b == 0) {
            throw new MyDivideByZeroException();
        }
        return a / b;
    }
}

public class MyDivideByZeroException : Exception {

    public MyDivideByZeroException() {
        HResult = -2147352558;
    }
}
于 2017-07-31T05:55:16.687 回答