C#中JavaScriptSerializer序列化接口未定义字段问题求助
为什么强制转换为接口后,JavaScriptSerializer仍序列化了接口未定义的字段?
核心原因
JavaScriptSerializer在序列化时,会反射对象的实际运行时类型(也就是Stam类),而非你代码里声明的引用类型(iStam接口)。哪怕你把Stam实例强制转换为iStam,运行时这个对象本质上还是Stam的实例——序列化器只会关心「这个对象到底是什么类型」,不会管你用什么类型的引用来持有它。
这就解释了为什么编译时_s看不到b字段,但序列化后b还是被包含进去:编译时的类型检查只是语法层面的限制,运行时对象的完整类型信息依然存在,序列化器会遍历该类型的所有公共成员(包括字段b)进行序列化。
解决方案
如果你想只序列化接口中定义的成员,可以试试以下几种方法:
1. 使用DataContract和DataMember特性(推荐)
通过特性明确标记哪些成员需要被序列化,JavaScriptSerializer会尊重这些标记:
using System.Runtime.Serialization; [DataContract] interface iStam { [DataMember] int a { get; set; } } [DataContract] class Stam : iStam { private int _a = 0; [DataMember] public int a { get { return _a; } set { _a = value; } } public int b = 0; // 无DataMember标记,不会被序列化 } void fun() { Stam s = new Stam(); iStam _s = (iStam)s; JavaScriptSerializer jss = new JavaScriptSerializer(); Console.WriteLine(jss.Serialize(_s)); // 输出: {"a":0} }
2. 手动创建匿名对象
只提取需要序列化的属性,序列化这个匿名对象:
void fun() { Stam s = new Stam(); var serializableObj = new { a = s.a }; JavaScriptSerializer jss = new JavaScriptSerializer(); Console.WriteLine(jss.Serialize(serializableObj)); // 输出: {"a":0} }
3. 换用支持接口序列化的工具
比如Newtonsoft.Json(Json.NET),它可以指定序列化时使用的类型(接口类型):
using Newtonsoft.Json; void fun() { Stam s = new Stam(); string json = JsonConvert.SerializeObject(s, typeof(iStam)); Console.WriteLine(json); // 输出: {"a":0} }
内容的提问来源于stack exchange,提问作者Guy Dafny
相关产品推荐
相关产品推荐

