我有一个正在序列化一些数据的类:

[Serializable]
public class SomeData {
    public int NumericField;
    public string StringField;
}


我有一个很好的便捷扩展方法:

public static string ToJson<T> (this T value) {
    // yay no compile-time checks for [Serializable]?
    if (!typeof(T).IsSerializable)
        throw new SerializationException("Object lacks [Serializable] attribute");

    var serializer = new DataContractJsonSerializer(typeof(T));

    using (var stream = new MemoryStream()) {
        using (var writer = JsonReaderWriterFactory.CreateJsonWriter(stream, Encoding.UTF8)) {
            serializer.WriteObject(writer, value);
        }

        return Encoding.UTF8.GetString(stream.ToArray());
    }
}


我确实希望我的类SomeData实现ISerializable,但是当我添加它时,被告知需要添加一个方法:

error CS0535: 'SomeData' does not implement interface member
System.Runtime.Serialization.ISerializable.GetObjectData(
System.Runtime.Serialization.SerializationInfo,
System.Runtime.Serialization.StreamingContext)'


问题在于,我希望它能够完全执行当前的操作,而且还要将ToJson<T>限制为ISerializable类,因此没有人会意外地将其传递给某些可避免的异常。像这样:

public static string ToJson<T> (this T value) where T : ISerializable


是否有GetObjectData的简洁实现或其他一些技巧,这些技巧将仅复制如果不添加ISerializable接口时所得到的确切行为?我想要一些我可以只包含在我继承的类中的东西,或者简明的东西(并始终完全相同),我可以将其粘贴到我只希望[Serializable]确实发生什么的所有类中。通用的东西。性能并不是一个大问题,但是我只能使用.Net Framework 3.5。

更新:

我非常愿意使用[DataContract]代替[Serializable],但是如果我这样做了,有没有一种通用的方式可以实现ISerializable,所以它确实可以实现[DataContract]如果我没有的话。实施ISerializable? (在您看到DataContract的任何地方,与Serializable相同的qn)

最佳答案

您根本不需要ISerializable,也不需要自己扔SerializationException。如果类型不可序列化,DataContractJsonSerializer将引发异常。
使用此序列化程序可序列化的类型实际上有几个选项:


可序列化的属性
DataContract属性
可序列化的接口
一无所有(适用于公共类型,并且序列化所有公共字段和属性)


让串行器执行检查将支持所有这些。

更新资料

在评论中进行了一些讨论之后,我想强调一下这一点:

永远不会有编译时检查可串行性(至少从C#5.0开始)。将对象标记为Serializable或什至实现ISerializable接口都不能保证序列化程序在对象图中不会遇到不可序列化的类型,并且在运行时不会引发异常。

10-01 17:19