使用C#反射创建ErrorType泛型类时,System.Fabric.FabricServiceNotFoundException报错
你的代码里GenerateDynamicErrorHandler函数的核心问题出在Type.GetType(typeName)这一步。对于System.Fabric.FabricServiceNotFoundException这类来自非默认程序集(比如System.Fabric.dll)的异常,仅用类型的FullName调用Type.GetType()会返回null——因为Type.GetType()默认只在当前执行程序集和mscorlib/System.Private.CoreLib中查找类型,跨程序集的类型需要程序集限定名才能被正确定位。
当Type.GetType(typeName)返回null后,后续的MakeGenericType调用会抛出异常,触发catch块里的ReflectionException,最终让这个异常走了反射错误的 fallback 分支,而不是预期的ErrorType<T>处理逻辑。
既然你已经拿到了Exception ex实例,完全不需要通过字符串去反向查找类型,直接用ex.GetType()就能获取到准确的类型对象,这比通过字符串查找可靠得多。修改后的GenerateDynamicErrorHandler函数如下:
private dynamic GenerateDynamicErrorHandler(Exception ex) { try { Type typeArgument = ex.GetType(); // 直接获取异常的类型,跳过Type.GetType的字符串查找 Type genericClass = typeof(ErrorType<>); Type constructedClass = genericClass.MakeGenericType(typeArgument); dynamic created = Activator.CreateInstance(constructedClass); return created; } catch { throw new ReflectionException(ex.GetType().FullName); } }
像ArgumentException、NullReferenceException这类常见异常都位于mscorlib或当前程序集内,Type.GetType(typeName)仅用FullName就能找到对应的类型,所以不会触发问题。而System.Fabric命名空间下的类型属于独立的程序集,必须通过程序集限定名(比如System.Fabric.FabricServiceNotFoundException, System.Fabric, Version=6.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35)才能被Type.GetType()定位到,但直接使用ex.GetType()可以完全避开这个问题。
内容的提问来源于stack exchange,提问作者Mu'aaz Joosuf

