如何从Object类型数组对象中取值?(ECMA-404 JSON序列化需求)
通用JSON数组序列化实现(适配ECMA-404标准)
问题背景
开发符合ECMA-404标准的JSON解析器,必须采用通用处理逻辑,不能使用int[] arr = obj as int[];这类针对具体类型的强转。当前需要从Object类型的数组变量中提取元素,完成SerializeArray函数的序列化逻辑,之前尝试反射未成功,参考相关方案也未解决问题。
现有代码
测试示例:
int[] array = new int[] { 0, 1, 2 }; object obj = array; // 需要从obj中获取元素值
已有序列化代码:
private static string ReadObject(object obj) { string json = "{"; TypedReference reference = __makeref(obj); foreach(var fromField in obj.GetType().GetFields()) { var toField = obj.GetType().GetField( fromField.Name, BindingFlags.Public | BindingFlags.Instance); object value = fromField.GetValueDirect(reference); if(value == null) json += toField.Name + ':' + "null" + ','; else json += toField.Name + ':' + WriteValue(value, value.GetType()) + ','; } json = json.Remove(json.Length - 1); json += '}'; return json; } public static string SerializeArray(object obj) { string json = "["; // 这里需要补充代码 return json; }
解决方案
利用所有数组类型均继承自System.Array基类的特性,实现通用数组遍历,无需针对具体类型强转。补全后的SerializeArray代码如下:
public static string SerializeArray(object obj) { string json = "["; // 转为Array基类,适配所有数组类型 Array array = obj as Array; if (array != null) { foreach (var element in array) { // 复用已有WriteValue处理元素序列化 string elementJson = element == null ? "null" : WriteValue(element, element.GetType()); json += elementJson + ','; } // 移除末尾多余逗号(避免空数组或单元素数组格式错误) if (array.Length > 0) { json = json.Remove(json.Length - 1); } } json += ']'; return json; }
关键说明
- 通用数组适配:
obj as Array是合法的通用转换,所有数组类型(int[]、string[]、自定义对象数组等)都继承自Array,不涉及具体类型强转,符合ECMA-404的通用处理要求。 - 逻辑复用:直接遍历
Array的元素,调用已有的WriteValue函数处理元素序列化,和ReadObject中的逻辑保持一致。 - 格式正确性:处理空数组(直接返回
[])和非空数组的末尾逗号问题,避免生成不符合标准的JSON。
补充:完善WriteValue逻辑
如果WriteValue尚未处理基本类型和嵌套结构,建议补充以下实现以保证完整序列化:
private static string WriteValue(object value, Type type) { // 处理数值类型 if (type == typeof(int) || type == typeof(long) || type == typeof(float) || type == typeof(double) || type == typeof(decimal)) { return value.ToString(); } // 处理布尔类型 if (type == typeof(bool)) { return value.ToString().ToLowerInvariant(); } // 处理字符串(需转义特殊字符) if (type == typeof(string)) { return $"\"{EscapeJsonString((string)value)}\""; } // 处理嵌套数组 if (type.IsArray) { return SerializeArray(value); } // 处理自定义对象 if (type.IsClass && type != typeof(string)) { return ReadObject(value); } // 默认处理(转为带引号的字符串) return $"\"{value.ToString()}\""; } // JSON字符串转义辅助函数(符合ECMA-404标准) private static string EscapeJsonString(string input) { if (string.IsNullOrEmpty(input)) return input; return input.Replace("\\", "\\\\") .Replace("\"", "\\\"") .Replace("\n", "\\n") .Replace("\r", "\\r") .Replace("\t", "\\t") .Replace("\b", "\\b") .Replace("\f", "\\f"); }
内容的提问来源于stack exchange,提问作者justSMTH
相关产品推荐
相关产品推荐

