3

我有一堂课,里面有一些我正在序列化的数据:

[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]如果我没有实现它会做什么ISerializableDataContract(与您看到的任何地方相同的 qn Serializable

4

3 回答 3

6

你根本不需要ISerializable,也不需要SerializationException自己扔。DataContractJsonSerializer如果类型不可序列化,则会抛出异常。使用此序列化程序可序列化类型实际上有几个选项:

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

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

更新

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

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

于 2012-04-22T07:46:25.093 回答
0
  1. 正如您自己评论的那样,添加一个空白接口并将其作为约束放在您的扩展方法中。您还可以将 ISerializable 添加为多个类型参数约束的 C# 泛型语法约束

  2. 另一种选择是继承实现 ISerializable 和所需方法的基类

于 2012-04-22T06:19:43.290 回答
0

若要解决此问题,请在转换后的 Visual C# .NET 类中实现 ISerializable.GetObjectData 方法。为此,在转换后的 Visual C# .NET 类中添加以下代码:

void System.Runtime.Serialization.ISerializable.GetObjectData(
    System.Runtime.Serialization.SerializationInfo info,
    System.Runtime.Serialization.StreamingContext context)
{
    // Code as required
}
于 2014-07-30T15:38:56.110 回答