【问题标题】:Test if a class can be serialized测试一个类是否可以序列化
【发布时间】:2011-01-25 16:22:39
【问题描述】:

我想创建一个通用方法来将类序列化为文本(用作网络组件的一部分) 方法应该是这样的:

public string SerializeToText<T>(T DataToSerialize);

方法内容将简单地执行 xml 序列化,我可以做到这一点。我想知道的是我是否可以检查 T 是否可以序列化:最好在编译时进行,但在运行时失败。

【问题讨论】:

  • 很确定这是一个骗子,至少有一个答案是一个完全的骗子stackoverflow.com/questions/81674/…
  • 不——这个问题主要询问编译时的检查。上一个问题只询问运行时检查。这里的许多答案可能是重复的,但这只是因为他们的作者没有足够仔细地阅读这个问题! :)

标签: c# generics xml-serialization


【解决方案1】:

一个类可以通过简单地将一个属性应用到它的定义来启用序列化。而且在 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】:

    你指的是这个吗?

    if (typeof(T).IsSerializable)
    

    【讨论】:

    • 查看 Jared 的回答,了解为什么它不那么简单。
    • 好的。 JaredPar 正在写他的答案时,我正在写我的答案,这就是为什么我在发布之前没有阅读它。
    【解决方案3】:

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

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

    [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
    

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

    【讨论】:

    猜你喜欢
    • 2018-08-19
    • 2010-09-19
    • 2011-08-12
    • 1970-01-01
    • 2020-05-31
    • 2020-03-20
    • 2012-01-17
    相关资源
    最近更新 更多