当我想要完全按照我没有添加ISerializable时的操作时,如何在具有[Serializable]的类上实现ISerializable?

fcr*_*ick 3 c# generics reflection serialization

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

[Serializable]
public class SomeData {
    public int NumericField;
    public string StringField;
}
Run Code Online (Sandbox Code Playgroud)

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

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());
    }
}
Run Code Online (Sandbox Code Playgroud)

我真的很喜欢我的课程SomeData实现ISerializable,但是当我添加它时,我被告知我需要添加一个方法:

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

问题只是我希望它完全按照目前的做法进行操作,但也限制ToJson<T>ISerializable类,因此没有人会不小心将它传递给可能引发可避免异常的东西.像这样:

public static string ToJson<T> (this T value) where T : ISerializable
Run Code Online (Sandbox Code Playgroud)

是否有一个简洁的实现GetObjectData或其他一些技巧,只会复制我没有添加ISerializable接口时会得到的确切行为?我想要的东西,我可以只包括在I类继承,或简洁的东西(总是一模一样的),我可以粘贴到所有,我只是想正是班[Serializable]确实发生.通用的东西.性能不是一个大问题,但我只能使用.Net Framework 3.5.

更新:

我非常愿意[DataContract]代替它使用[Serializable],但是如果我这样做,是否有一种我可以实现的通用方式,ISerializable所以它只是[DataContract]如果我没有实现它会做什么ISerializable呢?(与DataContract你看到的所有地方相同的qn Serializable)

Eli*_*bel 6

你根本不需要ISerializable,也不需要抛弃SerializationException自己.DataContractJsonSerializer如果类型不可序列化,将抛出异常.实际上有几种类型可以使用此序列化程序进行序列化:

  • Serializable属性
  • DataContract属性
  • 可ISerializable接口
  • 什么都没有(适用于公共类型并序列化所有公共字段和属性)

让序列化程序执行检查将支持所有这些.

更新

经过评论中的一些讨论后,我想强调一点:

永远不会有可编译性的编译时检查(至少从C#5.0开始).将对象标记为Serializable甚至实现ISerializable接口并不能保证序列化程序不会在对象图中遇到非可序列化类型并在运行时抛出异常.