zoukankan      html  css  js  c++  java
  • 使用反射捕捉到TargetInvocationException异常

    环境:Unity2017、.NET4.6

    问题出现描述:自定义了JSON格式转换异常类,通过反射Invoke反射方法,抛出异常时,捕捉的异常是System.Reflection.TargetInvocationException而不是JSON格式转换异常。
    源码简化如下:

    /// <summary>
    /// JSON格式转换类
    /// </summary>
    public static class JSonConvert
    {
        public static void Convert()
        {
    		throw new JsonToClassEX("转换失败");
        }
    }
    
    /// <summary>
    /// JSON格式异常类
    /// </summary>
    public class JsonToClassEX : Exception
    {
        public JsonToClassEX(string message) : base(message)
        {
        }
    }
    

    反射方法捕捉异常

    /// <summary>
    /// 反射方法捕捉异常
    /// </summary>
    public class NewBehaviourScript : MonoBehaviour
    {
        void Start()
        {
            try
            {
                Type t = typeof(JSonConvert);
                MethodInfo method = t.GetMethod("Convert");
                method.Invoke(method.ReflectedType, null);
            }
            catch (JsonToClassEX e)
            {
                Debug.LogError("JsonToClassEX:" + e.Message);
            }
            catch (Exception e)
            {
                Debug.Log(e.GetType());
                Debug.Log(e.InnerException.GetType());
                Debug.LogError("Exception:" + e.Message);
            }
        }
    }
    

    输出结果:
    输出结果
    可以看到catch (JsonToClassEX e)块并没有进入,而是通过catch (Exception e)块捕捉到。
    此外捕捉的异常是:System.Reflection.TargetInvocationException,而我们自定义的异常类被封成了异常的的InnerException属性。

    分析原因:

    这是由于CLR在调用反射方法,改变了异常,重新抛出了异常,但保留了JSON格式异常的堆栈信息。这是由于.NET内部机制导致。

    解决方法:

    第一种:在catch (Exception e)或catch (TargetInvocationException e) 处理异常
    既然被封成了内部异常,那么我直接可以通过InnerException属性判断类型进行处理。

            catch (Exception e) when (e.InnerException.GetType() == typeof(JsonToClassEX))
            {
    			//处理异常
            }
    

    第二种:我就是想捕捉到JSON格式异常,我不要通过InnerException属性(真是任性呢)
    可以通过在反射方法内捕捉,修改JSonConvert类Convert方法如:

        public static void Convert()
        {
            try
            {
                throw new JsonToClassEX("转换失败");
            }
            catch (Exception e)
            {
                Debug.LogWarning(e);
                //throw;如果想同时捕捉到argetInvocationException异常,请取消注释
            }
    
        }
    

    这样捕捉到JsonToClassEX异常就不会抛出,若想继续捕捉到TargetInvocationException 异常就取消throw的注释。

  • 相关阅读:
    Srt字幕文件解析
    有意思的一些处理
    CMSampleBufferRef转换
    不知为什么的警告和报错
    X Postgres copy命令导入导出数据
    X Oracle打Patch报错Missing command :fuser
    X wal_segment_size参数的理解与调优
    X PostgreSQL 11、12 开启归档日志
    X 手动安装postgresql扩展插件
    P1501 [国家集训队]Tree II
  • 原文地址:https://www.cnblogs.com/craft0625/p/14343722.html
Copyright © 2011-2022 走看看