在阅读MSDN参考资料后,我仍然对何时使用KnownType属性有疑问。我知道该属性将类型信息传递给序列化程序,但何时需要?当被序列化的类具有基类类型的引用时,是否适合,并且有可以设置为这些引用的上传衍生类?
此外,过度使用属性有什么缺点吗?例如,在前面的示例中,如果序列化类使用KnownType(baseClass)标记,即使存在对该类型的显式引用?
答案 0 :(得分:65)
[KnownType]
需要告诉它有关子类型的信息。 不使用它的缺点是以下方法不起作用:
[DataContract]
class Foo {}
[DataContract]
class Bar : Foo {}
在WCF接口上返回一个方法:
public Foo GetFoo() { return new Bar(); }
如果没有该属性,序列化程序(特别是对于mex /代理生成的类型)将无法了解Bar
,它将失败。使用属性:
[DataContract, KnownType(typeof(Bar))]
class Foo {}
将工作。这仅适用于DataContractSerializer
- NetDataContractSerializer
您以不同的方式获取类型数据。
答案 1 :(得分:7)
如果您在架构中使用XSD“继承”。
你已经倒退了; KnownTypeAttribute应用于基类,并命名可能作为对基类的引用传递的所有派生类。
例如:
...
KnownType(typeof(POBoxAddress))
KnownType(typeof(StreetAddress))
KnownType(typeof(SingleLineAddress))
KnownType(typeof(ParsedAddress))
public abstract class AddressBase
{
...
}
答案 2 :(得分:6)
在序列化非接口类型(如接口或基类)时,必须使用KnownType属性。 WCF序列化程序必须知道接口或继承类的所有可能实现。它不知道的任何实现都会导致序列化异常。
可以在此SO question
中找到一个可能的用法答案 3 :(得分:0)
对于以下情况也很有用:
[DataContract]
[knownType(typeof(Person))]
public class KeyValue
{
[DataMember]
public string key {get; set;}
[DataMember]
public string value {get; set;}
// rest of the code
}
现在假设值包含其他类的一些对象说Person。然后这一切工作你必须添加knownType(typeof(Person))