You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何阻止MissingMethodException中断程序后续执行?

MissingMethodException未被try/catch捕获的原因及解决方案

问题背景

我为学生提供一个DLL文件框架,要求他们用.NET C#填充其中方法。学生将编译后的DLL放入我的「进度检测」应用,该应用会检查方法完成情况并给出完成百分比。

应用中针对每个可能缺失或损坏的内容,我使用try/catch块处理:执行成功则向布尔列表添加true,捕获错误或未满足条件则添加false,代码如下:

List<bool> testResults;

testResults = new List<bool>(); 
Print("Starting Engine Tools testing.");

try 
{ 
    EngineTools.Print("Testing Print");
    testResults.Add(true); 
} catch (Exception ex)
{
    Print("Print Method in EngineTools Failed");
    testResults.Add(false);
}

正常使用合规DLL时程序运行正常,但替换为移除所有内容的测试用坏DLL后,调用EngineTools.Print(object message)时抛出:

"Unhandled Exception: System.MissingMethodException: Method not found: 'Void GameEngine.EngineTools.Print(System.Object)'."

该异常未被try/catch捕获,导致程序终止,无法执行后续测试,也不显示最终得分。


核心原因

MissingMethodException是在JIT(即时编译)阶段抛出的,而非方法执行阶段。你的try/catch块只能捕获方法调用执行过程中产生的异常,但当CLR尝试编译包含EngineTools.Print调用的代码段时,发现找不到目标方法,会直接抛出该异常——此时代码还未进入try块的执行逻辑,自然无法被捕获。


解决方法

1. 使用反射动态调用方法

通过反射在运行时动态查找并调用目标方法,将方法查找的过程纳入try/catch块,从而捕获MissingMethodException:

try
{
    Type engineToolsType = typeof(EngineTools);
    // 匹配方法名和参数类型
    MethodInfo printMethod = engineToolsType.GetMethod("Print", new Type[] { typeof(object) });
    if (printMethod != null)
    {
        // 静态方法传入null作为实例参数
        printMethod.Invoke(null, new object[] { "Testing Print" });
        testResults.Add(true);
    }
    else
    {
        Print("Print Method in EngineTools not found");
        testResults.Add(false);
    }
}
catch (Exception ex)
{
    Print($"Print Method in EngineTools Failed: {ex.Message}");
    testResults.Add(false);
}

反射会在运行时动态检查方法是否存在,所有相关异常都能被try/catch捕获,不会导致程序终止。

2. 基于抽象接口实现晚绑定

定义一个抽象接口(如IEngineTools),让学生的DLL实现该接口,检测程序通过接口调用方法,并使用Assembly.Load动态加载DLL创建实例:

// 定义接口
public interface IEngineTools
{
    void Print(object message);
}

// 检测程序中的调用逻辑
try
{
    // 动态加载学生的DLL
    Assembly studentAssembly = Assembly.LoadFrom("StudentEngine.dll");
    Type engineToolsType = studentAssembly.GetType("GameEngine.EngineTools");
    if (typeof(IEngineTools).IsAssignableFrom(engineToolsType))
    {
        IEngineTools engineTools = (IEngineTools)Activator.CreateInstance(engineToolsType);
        engineTools.Print("Testing Print");
        testResults.Add(true);
    }
    else
    {
        Print("EngineTools does not implement IEngineTools");
        testResults.Add(false);
    }
}
catch (Exception ex)
{
    Print($"Print Method in EngineTools Failed: {ex.Message}");
    testResults.Add(false);
}

这种方式遵循依赖倒置原则,避免了编译时对具体实现的依赖,所有加载和调用异常都能被捕获。


补充提示

  • 除MissingMethodException外,TypeLoadException、MissingFieldException等也属于JIT阶段抛出的异常,常规try/catch无法捕获,需用反射或接口晚绑定处理。
  • 使用反射时需严格匹配方法名和参数类型,避免因参数不一致引发AmbiguousMatchException。

内容的提问来源于stack exchange,提问作者Fr0z3n5un

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 18:25:17