什么时候适合使用 KnownType 属性?

Posted

技术标签:

【中文标题】什么时候适合使用 KnownType 属性?【英文标题】:When is it appropriate to use the KnownType attribute? 【发布时间】:2011-03-11 05:21:01 【问题描述】:

阅读 MSDN 参考后,我仍然对何时使用 KnownType 属性有疑问。我知道该属性将类型信息传达给序列化程序,但是什么时候需要呢?当被序列化的类具有基类类型的引用并且存在可以设置为这些引用的向上转换派生类时是否合适?

此外,过度使用该属性有什么缺点吗?例如,在前面的示例中,如果序列化的类被标记为 KnownType(baseClass),即使有对该类型的显式引用?

【问题讨论】:

【参考方案1】:

[KnownType] 需要告诉它子类型。 not 使用它的缺点是以下内容不起作用:

[DataContract]
class Foo 

[DataContract]
class Bar : Foo 

使用 WCF 接口上的方法返回:

public Foo GetFoo()  return new Bar(); 

如果没有该属性,序列化程序(尤其是对于 mex/proxy 生成的类型)不会知道 Bar,它会失败。带属性:

[DataContract, KnownType(typeof(Bar))]
class Foo 

工作。这仅适用于DataContractSerializer - 使用NetDataContractSerializer,您以不同的方式获取类型数据。

【讨论】:

【参考方案2】:

在序列化接口或基类等非具体类型时,KnownType 属性是必需的。 WCF 序列化程序必须知道接口或继承类的所有可能实现。任何它不知道的实现都会导致序列化异常。

一个可能的用法可以在这个SO question中找到

【讨论】:

【参考方案3】:

如果您在架构中使用 XSD“继承”。

你把它弄反了; KnownTypeAttribute 应用于基类并命名所有可能作为对基类的引用传递的派生类。

例如:

...
[KnownType(typeof(POBoxAddress))]
[KnownType(typeof(StreetAddress))]
[KnownType(typeof(SingleLineAddress))]
[KnownType(typeof(ParsedAddress))]
public abstract class AddressBase

    ...

【讨论】:

【参考方案4】:

对于以下情况也很有用:

[DataContract]
[knownType(typeof(Person))]
public class KeyValue

  [DataMember]
  public string key get; set;

  [DataMember]
  public string value get; set;

  // rest of the code

现在假设 value 包含其他类的一些对象,比如 Person。那么这一切你必须添加 knownType(typeof(Person))

【讨论】:

以上是关于什么时候适合使用 KnownType 属性?的主要内容,如果未能解决你的问题,请参考以下文章

为每个派生类避免 KnownType 属性的公认方法

在 SvcUtil 和 WSDL 代码生成期间抓取 KnownType 属性

什么时候适合使用 Map 而不是 Object ?学到了~

什么时候适合使用 NOLOCK?

什么时候适合使用虚方法?

什么时候不适合使用派生表?