Comment puis-je ajouter une contrainte de type pour inclure quelque chose de sérialisable dans une méthode générique?

StackOverflow https://stackoverflow.com/questions/945495

Question

Ma méthode générique doit sérialiser l'objet qui lui est transmis, mais insistant simplement pour qu'il implémente iSérialisable ne semble pas fonctionner. Par exemple, j'ai une structure renvoyée d'un service Web (marqué de SerializableAtTribute) qui sérialise à XML très bien, mais, comme prévu, le compilateur C # se plaint.

Existe-t-il un moyen de vérifier que l'objet est sérialisable avant d'essayer de le sérialiser, ou, mieux encore, un moyen d'utiliser le where Le mot-clé pour vérifier l'objet convient?

Voici ma méthode complète:

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);
}

Et 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();
    }
}

Si cela n'est pas possible, quelle est la meilleure façon d'effectuer un contrôle qu'un objet est sérialisable au moment de l'exécution?

Était-ce utile?

La solution

Vous ne pouvez pas le faire totalement via des contraintes génériques, mais vous pouvez faire quelques choses pour aider:

1) Mettez le Nouveau() contrainte sur le type générique (pour permettre la possibilité de désérialiser et de s'assurer que le XMLSerializer ne se plaint pas d'un manque de ctor par défaut):

where T : new()

2) Sur la première ligne de votre méthode, gérant la sérialisation (ou constructeur ou ailleurs, vous n'avez pas à le répéter encore et encore), vous pouvez effectuer ce chèque:

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

Bien sûr, il y a toujours la possibilité d'exceptions d'exécution lorsque vous essayez de sérialiser un type, mais cela couvrira les problèmes les plus évidents.

Autres conseils

J'ai écrit un article de blog sur ce sujet que vous pourriez trouver utile. Il va principalement dans la sérialisation binaire, mais les concepts sont applicables à la plupart des formats de sérialisation.

Le long et le court est

  • Il n'y a aucun moyen d'ajouter une contrainte générique fiable
  • La seule façon de vérifier et de voir si un objet a été La série est de la sérialiser et de voir si l'opération réussit

La seule façon de savoir si un objet est sérialisable est d'essayer de le sérialiser.

En fait, vous demandiez comment savoir si un type "est sérialisable", mais la question réelle sera par rapport aux objets. Certains cas d'un type peuvent ne pas être sérialisables même si le type est marqué [sérialisable]. Par exemple, que se passe-t-il si l'instance contient des références circulaires?

À la place de

XmlSerializer xmlSerializer = new XMLSerializer (typeof (t));

essayer

XmlSerializer xmlSerializer = new XMLSerializer (message.getType ());

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top