我正在寻找一种简单的方法来检查C#中的对象是否可序列化.
我们知道,通过实现ISerializable接口或将[Serializable]放在类的顶部,可以使对象可序列化.
我正在寻找的是一种快速检查方法,而无需反映类以获得它的属性.接口可以快速使用is语句.
使用@Flard的建议这是我提出的代码,尖叫是有更好的方法.
private static bool IsSerializable(T obj)
{
return ((obj is ISerializable) || (Attribute.IsDefined(typeof (T), typeof (SerializableAttribute))));
}
Run Code Online (Sandbox Code Playgroud)
或者甚至更好地获取对象的类型,然后在类型上使用IsSerializable属性:
typeof(T).IsSerializable
Run Code Online (Sandbox Code Playgroud)
请记住,这似乎只是我们正在处理的类,如果类包含其他类,您可能想要检查它们或尝试序列化并等待错误,如@pb指出的那样.
lep*_*pie 114
你在这个Type
班上有一个可爱的财产IsSerializable
.
Pau*_*enk 41
您将不得不检查序列化为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);
}
}
Run Code Online (Sandbox Code Playgroud)
Mik*_*e_G 17
这是一个老问题,可能需要针对.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)
}
Run Code Online (Sandbox Code Playgroud)
正如其他人所指出的那样使用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
Run Code Online (Sandbox Code Playgroud)
因此,即使您确定类型的特定实例是可序列化的,通常也不能确定所有实例都是如此.
Attribute.IsDefined(typeof (YourClass), typeof (SerializableAttribute));
Run Code Online (Sandbox Code Playgroud)
可能涉及水下反射,但最简单的方法呢?
这是一个3.5变体,它使用扩展方法使所有类都可用.
public static bool IsSerializable(this object obj)
{
if (obj is ISerializable)
return true;
return Attribute.IsDefined(obj.GetType(), typeof(SerializableAttribute));
}
Run Code Online (Sandbox Code Playgroud)