You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何序列化包含接口类型属性的Person类?

解决接口类型属性的序列化问题

序列化包含接口类型属性的类时抛出System.NotSupportedException,是因为大多数序列化器无法直接处理接口——接口本身不能被实例化,序列化器需要明确知道要序列化的具体类型。以下是几种可行的解决办法:

1. 替换接口属性为具体实现类

直接把Person类中的INames类型属性改成具体的Names类,这是最简单直接的方案:

public class Person
{
    public Names Names { get; set; }
    public double WeightKg { get; set; }
    public double HeightCm { get; set; }
}

这样序列化器可以直接识别具体类型,无需额外配置。

2. 给序列化器指定接口的具体实现类型(以Json.NET为例)

如果必须保留接口类型,可以通过配置序列化器的类型信息来解决。比如使用Json.NET的TypeNameHandling,让序列化器在输出中添加类型标识:

序列化代码

var person = new Person 
{ 
    Names = new Names { First = "John", Last = "Doe" }, 
    WeightKg = 70, 
    HeightCm = 175 
};
string json = JsonConvert.SerializeObject(person, new JsonSerializerSettings
{
    TypeNameHandling = TypeNameHandling.Auto
});

反序列化代码

Person deserializedPerson = JsonConvert.DeserializeObject<Person>(json, new JsonSerializerSettings
{
    TypeNameHandling = TypeNameHandling.Auto
});

TypeNameHandling.Auto会自动在需要的地方(比如接口类型)添加类型信息,帮助序列化器识别具体实现类。

3. 使用DataContractSerializer并声明已知类型

如果使用WCF的DataContractSerializer,可以通过[KnownType]特性告诉序列化器接口对应的具体实现类:

[DataContract]
[KnownType(typeof(Names))]
public class Person
{
    [DataMember]
    public INames Names { get; set; }
    [DataMember]
    public double WeightKg { get; set; }
    [DataMember]
    public double HeightCm { get; set; }
}

[DataContract]
public class Names : INames
{
    [DataMember]
    public string First { get; set; }
    [DataMember]
    public string Last { get; set; }
}

public interface INames
{
    string First { get; set; }
    string Last { get; set; }
}

[KnownType(typeof(Names))]标记告诉序列化器,处理INames类型时可以接受Names类的实例。

4. 自定义序列化逻辑

如果以上方案都不适用,可以手动实现序列化逻辑。比如针对BinaryFormatter实现ISerializable接口:

[Serializable]
public class Person : ISerializable
{
    public INames Names { get; set; }
    public double WeightKg { get; set; }
    public double HeightCm { get; set; }

    public Person() { }

    protected Person(SerializationInfo info, StreamingContext context)
    {
        // 反序列化时直接读取具体类型
        Names = (Names)info.GetValue("Names", typeof(Names));
        WeightKg = info.GetDouble("WeightKg");
        HeightCm = info.GetDouble("HeightCm");
    }

    public void GetObjectData(SerializationInfo info, StreamingContext context)
    {
        // 序列化时将接口属性当作具体类型写入
        info.AddValue("Names", Names, typeof(Names));
        info.AddValue("WeightKg", WeightKg);
        info.AddValue("HeightCm", HeightCm);
    }
}

通过手动控制序列化和反序列化的过程,强制将接口类型转换为具体实现类处理。


内容的提问来源于stack exchange,提问作者user98

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 01:35:19