如何确定C#调用API返回的未知类型来源 实现正确类型转换
可用解决方案(按实现成本从低到高排序)
方案1:使用dynamic关键字实现动态调用
如果你能明确知道CADDrawing类型的所有属性、方法名称和调用规则,这是最简便的实现方式,不需要提前知道类型定义,运行时会自动匹配成员:
object drawingObj = DrawingSoapLoader.GetDrawing(ITEM_NUMBER, REVISION_CODE, DRAWING_TYPE); // 先校验类型名称,避免后续调用报错 if (drawingObj.GetType().Name == "CADDrawing") { dynamic drawing = drawingObj; // 直接按你需要的逻辑调用属性、方法即可,示例如下 int drawingId = drawing.Id; byte[] fileContent = drawing.ExportFile(); // 其余业务逻辑正常编写 }
注意:该方式没有编译期类型校验,成员名称、参数写错会在运行时抛出异常,适合成员数量少、规则明确的场景。
方案2:使用反射访问类型成员
如果需要更高的可控性,可以通过反射主动获取成员再操作,可以提前判断成员是否存在,避免未处理的运行时异常:
object drawing = DrawingSoapLoader.GetDrawing(ITEM_NUMBER, REVISION_CODE, DRAWING_TYPE); Type cadType = drawing.GetType(); if (cadType.Name == "CADDrawing") { // 读取属性示例 var idProperty = cadType.GetProperty("Id"); if (idProperty != null) { int drawingId = (int)idProperty.GetValue(drawing); } // 调用无参方法示例 var exportMethod = cadType.GetMethod("ExportFile", Type.EmptyTypes); if (exportMethod != null) { byte[] fileContent = (byte[])exportMethod.Invoke(drawing, null); } }
方案3:自定义匹配类+序列化转换(即你提到的自行创建本地类方案)
如果需要强类型开发体验、有编译期校验,该方案是最优选择:
- 先在本地项目中创建和返回的
CADDrawing结构完全一致的自定义类,属性名、类型完全匹配即可 - 通过序列化+反序列化的方式完成转换,示例使用System.Text.Json实现:
// 本地自定义类 public class LocalCADDrawing { public int Id { get; set; } public string ItemNumber { get; set; } public string RevisionCode { get; set; } public byte[] DrawingContent { get; set; } // 其余你需要用到的属性按实际结构补充即可 } // 转换逻辑 object drawing = DrawingSoapLoader.GetDrawing(ITEM_NUMBER, REVISION_CODE, DRAWING_TYPE); if (drawing.GetType().Name == "CADDrawing") { string json = JsonSerializer.Serialize(drawing); LocalCADDrawing cadDrawing = JsonSerializer.Deserialize<LocalCADDrawing>(json); // 后续直接使用强类型的cadDrawing对象即可 }
该方式的优势是后续业务代码完全为强类型,开发效率高、出错概率低,仅需要一次性完成自定义类的定义,序列化带来的性能损耗在绝大多数业务场景下可以忽略。
为什么不能直接强转?
你当前获取的CADDrawing类型是SOAP客户端运行时动态生成的程序集内的类型,每次运行程序集名称都会变化,无法在编译期固定引用,因此不存在编译期可识别的同类型对象,不能直接做强制类型转换。
内容的提问来源于stack exchange,提问作者Kira Resari
相关产品推荐
相关产品推荐

