如何检查对象是否可在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) }