2010-03-09 91 views
3

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

public string SerializeToText<T>(T DataToSerialize); 

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

+0

很确定这是一个骗局,至少有一个答案是一个确切的dupe http:// stackoverflow。com/questions/81674/how-to-check-if-an-object-is-serializable-in-c – 2010-03-09 23:26:19

+0

不是 - 这个问题主要是关于在编译时检查的问题。前一个问题只是询问运行时检查。这里的许多答案可能是重复的,但仅仅是因为他们的作者没有仔细阅读这个问题! :) – 2010-03-09 23:28:39

回答

4

单个最可靠的方法来测试,看看对象序列化是序列化它。如果成功,那么该对象是可序列化的,如果抛出则不可序列化。

注意这不是未来成功的预测因素,而只是过去的成功。对象改变它的状态当然不可能是可序列化的。例如

[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 

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

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的实现。这样的框架从一开始就对所有序列化的使用进行了类型安全性,而不是试图在之后使用它,这是不可能的。

这一切都涉及一定数量的车轮改造,但有时你需要一个更圆的车轮。

-1

你是指这个吗?

if (typeof(T).IsSerializable) 
+0

查看Jared的答案,为什么它不那么简单。 – 2010-03-09 23:26:57

+0

好的。当JaredPar写他的答案时,我正在写答案,这就是为什么我没有在发布之前阅读它。 – Javier 2010-03-09 23:32:24