测试是否可以序列化类

时间:2010-03-09 23:18:04

标签: c# generics xml-serialization

我想创建一个通用方法来将类serizlize到text(用作网络组件的一部分) 方法应该是这样的:

public string SerializeToText<T>(T DataToSerialize);

方法内容只是执行xml序列化,我可以这样做。我想知道的是,我是否可以检查T是否可以序列化:最好是在编译时,但在运行时失败。

3 个答案:

答案 0 :(得分:5)

测试和查看对象是否可序列化的最可靠的方法是序列化它。如果成功则该对象是可序列化的,如果它抛出然后它不可序列化。

请注意,这不是未来成功的预测因素,而是过去成功的预测因素。一个对象当然可以改变它的状态,使其不再可序列化。例如

[Serialiable] 
class Foo { 
  public object Field;
}
class Bar { }

var value = new Foo() { Field1 = 42; } // value is serializable
value.Field1 = new Bar();  // value is no longer serializable

我写了一篇关于确定对象是否可序列化的问题的冗长的博客文章。它深入讨论了这种方法的问题。

答案 1 :(得分:0)

只需将属性应用于其定义,即可启用类的序列化。并且C#中没有办法发生编译时错误,因为类型缺少属性,所以不,你不能捕获在编译时序列化不可序列化类型的尝试。

如果使用标准库方法进行序列化,那么任何序列化不支持它的类的尝试都会产生异常,所以你不需要做任何特殊的事情来在运行时检查它。

还有一点,使您的包装方法通用。参数可以是任何类型,没有可以有效限制它的约束,所以它也可能是一个普通的object

但是,如果您避免使用内置的.NET序列化框架,则可以开发自己的编译时检查。您必须适当地使用类型系统 - 也就是说,定义任何可序列化类型必须实现的接口。然后,您的SerializeToText方法将接受对该界面的引用。

interface ICanSerialize
{
    void Serialize(ISerializeMedium m);
}

interface ISerializeMedium
{
    void Serialize(string name, ref int value);
    void Serialize(string name, ref bool value);
    void Serialize(string name, ref string value);
    void Serialize<T>(string name, ref T value) where T : ICanSerialize;
    void Serialize<T>(string name, ref ICollection<T> value) where T : ICanSerialize;

    // etc.
}

可序列化类型如下所示:

class C : ICanSerialize
{
    string _firstName;
    bool _happy;

    public void Serialize(ISerializeMedium m)
    {
        m.Serialize("firstName", ref _firstName);
        m.Serialize("happy", ref _happy);
    }
}

然后你只需要ISerializeMedium的实现。这样的框架从一开始就对序列化的所有用途强加了类型安全,而不是试图在之后使用它,这是不可能的。

这一切都涉及一定数量的轮子重新发明,但有时你需要一个圆形轮。

答案 2 :(得分:-1)

你指的是这个吗?

if (typeof(T).IsSerializable)