如何检查对象是否可在C#中序列化

时间:2020-03-05 18:58:29  来源:igfitidea点击:

我正在寻找一种简单的方法来检查Cis中的对象是否可序列化。

众所周知,我们可以通过实现ISerializable接口或者将[Serializable]放置在类的顶部来使对象可序列化。

我正在寻找的是一种无需检查类即可获取其属性的快速方法。使用is语句,该接口将很快。

使用@Flard的建议,这是我想出的代码,尖叫是有更好的方法的。

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

甚至更好的方法是获取对象的类型,然后在该类型上使用IsSerializable属性:

typeof(T).IsSerializable

请记住,尽管这似乎只是我们要处理的类,如果该类包含其他类,我们可能要检查所有这些类,或者尝试进行序列化并等待@pb指出的错误。

解决方案

回答

Attribute.IsDefined(typeof (YourClass), typeof (SerializableAttribute));

可能涉及水下反射,但是最简单的方法是?

回答

我们将必须检查序列化对象图中所有类型的serializable属性。最简单的方法是尝试序列化对象并捕获异常。 (但这不是最干净的解决方案)。 Type.IsSerializable并检查serializalbe属性不考虑该图。

样本

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

回答

我们在类型类上有一个可爱的属性,称为" IsSerializable"。

回答

这是一个3.5版本,使用扩展方法使其可用于所有类。

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

回答

正如其他人指出的那样,使用Type.IsSerializable。

可能不值得尝试反映和检查对象图中的所有成员是否可序列化。

可以将成员声明为可序列化的类型,但实际上将其实例化为不可序列化的派生类型,如下面的示例所示:

[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

因此,即使我们确定类型的特定实例是可序列化的,也通常不能确保所有实例都适用。

回答

这是一个古老的问题,可能需要针对.NET 3.5+进行更新。如果类使用DataContract属性,则Type.IsSerializable实际上可以返回false。这是我使用的摘要,如果发臭,请告诉我:)

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

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

}