如何添加类型约束以包含可在通用方法中序列化的任何内容?

Mat*_*ley 43 c# generics attributes serializable

我的泛型方法需要序列化传递给它的对象,但只是坚持它实现ISerializable似乎不起作用.例如,我有一个从Web服务(标记为SerializableAttribute)返回的结构,它可以很好地序列化为xml,但正如预期的那样,C#编译器会抱怨.

有没有办法在尝试序列化之前检查对象是否可序列化,或者更好的是,使用where关键字检查对象的方法是否合适?

这是我的完整方法:

public static void Push<T>(string url, T message)
        where T : ISerializable
{
    string xml = SerializeMessage(message);

    // Send the message to Amazon SQS
    SendMessageRequest sendReq = new SendMessageRequest { QueueUrl = url, MessageBody = xml };
    AmazonSQSClient client = new AmazonSQSClient(S3User, S3Pass);
    client.SendMessage(sendReq);
}
Run Code Online (Sandbox Code Playgroud)

和SerializeMessage:

private static string SerializeMessage<T>(T message)
{
    XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));
    using (StringWriter stringWriter = new StringWriter())
    {
        xmlSerializer.Serialize(stringWriter, message);
        return stringWriter.ToString();
    }
}
Run Code Online (Sandbox Code Playgroud)

如果这不可能,那么在运行时检查对象是否可序列化的最佳方法是什么?

Ada*_*lls 38

你不能完全通过通用约束来做到这一点,但你可以做一些事情来帮助:

1)将new()约束放在泛型类型上(以启用反序列化的功能并确保XmlSerializer不会抱怨缺少默认ctor):

where T : new()
Run Code Online (Sandbox Code Playgroud)

2)在处理序列化的方法的第一行(或构造函数或其他任何你不必反复重复的方法),你可以执行此检查:

if( !typeof(T).IsSerializable && !(typeof(ISerializable).IsAssignableFrom(typeof(T)) ) )
    throw new InvalidOperationException("A serializable Type is required");
Run Code Online (Sandbox Code Playgroud)

当然,在尝试序列化类型时仍然存在运行时异常的可能性,但这将涵盖最明显的问题.

  • 这个答案是不正确的,因为它会给出误报.typeof(T)计算为System.Runtime.Type,它是ISerializable,因此它将始终计算为true.改为使用它... if(!typeof(T).IsSerializable &&!(typeof(ISerializable).IsAssignableFrom(typeof(T)))) (3认同)

Jar*_*Par 10

我写了一篇关于这个主题的长篇博客文章,你可能会觉得有帮助.它主要用于二进制序列化,但这些概念适用于大多数序列化格式.

它的长短是

  • 无法添加可靠的通用约束
  • 检查并查看对象是否可序列化的唯一方法序列化它并查看操作是否成功