93 votes

Comment vérifier si un objet est sérialisable en C#

Je cherche un moyen simple de vérifier si un objet en C# est sérialisable.

Comme nous le savons, vous rendez un objet sérialisable soit en implémentant la fonction ISerializable ou en plaçant l'interface [Serializable] au premier rang de la classe.

Ce que je cherche, c'est un moyen rapide de vérifier cela sans avoir à refléter la classe pour obtenir ses attributs. L'interface serait rapide et utiliserait un est déclaration.

En utilisant la suggestion de @Flard c'est le code que j'ai trouvé, criez si il y a une meilleure façon.

private static bool IsSerializable(T obj)
{
    return ((obj is ISerializable) || (Attribute.IsDefined(typeof (T), typeof (SerializableAttribute))));
}

Ou encore mieux, obtenez simplement le type de l'objet, puis utilisez la propriété IsSerializable sur le type :

typeof(T).IsSerializable

Rappelez-vous cependant que cela semble ne concerner que la classe avec laquelle nous travaillons ; si la classe contient d'autres classes, vous voudrez probablement les vérifier toutes ou essayer de sérialiser et attendre les erreurs comme @pb l'a souligné.

115voto

leppie Points 67289

Vous avez une belle propriété sur la classe Type appelée IsSerializable.

41voto

pb. Points 4609

Vous allez devoir vérifier tous les types dans le graphe des objets sérialisés pour l'attribut sérialisable. Le moyen le plus simple est d'essayer de sérialiser l'objet et d'attraper l'exception. (Mais ce n'est pas la solution la plus propre). Type.IsSerializable et la vérification de l'attribut sérialisable ne prennent pas en compte le graphe.

Echantillon

[Serializable]
public class A
{
    public B B = new B();
}

public class B
{
   public string a = "b";
}

[Serializable]
public class C
{
    public D D = new D();
}

[Serializable]
public class D
{
    public string d = "D";
}

class Program
{
    static void Main(string[] args)
    {

        var a = typeof(A);

        var aa = new A();

        Console.WriteLine("A: {0}", a.IsSerializable);  // true (WRONG!)

        var c = typeof(C);

        Console.WriteLine("C: {0}", c.IsSerializable); //true

        var form = new BinaryFormatter();
        // throws
        form.Serialize(new MemoryStream(), aa);
    }
}

17voto

Mike_G Points 4519

Il s'agit d'une ancienne question, qui doit peut-être être mise à jour pour .NET 3.5+. Type.IsSerializable peut en fait retourner false si la classe utilise l'attribut DataContract. Voici un extrait que j'utilise, si c'est mauvais, dites-le moi :)

public static bool IsSerializable(this object obj)
{
    Type t = obj.GetType();

     return  Attribute.IsDefined(t, typeof(DataContractAttribute)) || t.IsSerializable || (obj is IXmlSerializable)

}

9voto

Joe Points 60749

Utilisez Type.IsSerializable comme d'autres l'ont indiqué.

Il n'est probablement pas utile d'essayer de réfléchir et de vérifier si tous les membres du graphe d'objets sont sérialisables.

Un membre peut être déclaré comme un type sérialisable, mais en fait être instancié comme un type dérivé qui n'est pas sérialisable, comme dans l'exemple artificiel suivant :

[Serializable]
public class MyClass
{
   public Exception TheException; // serializable
}

public class MyNonSerializableException : Exception
{
...
}

...
MyClass myClass = new MyClass();
myClass.TheException = new MyNonSerializableException();
// myClass now has a non-serializable member

Par conséquent, même si vous déterminez qu'une instance spécifique de votre type est sérialisable, vous ne pouvez pas en général être sûr que ce sera le cas pour toutes les instances.

5voto

Michael Meadows Points 15277

Voici une variation 3.5 qui le rend disponible à toutes les classes en utilisant une méthode d'extension.

public static bool IsSerializable(this object obj)
{
    if (obj is ISerializable)
        return true;
    return Attribute.IsDefined(obj.GetType(), typeof(SerializableAttribute));
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X