数据协定序列化程序要求超类知道子类

| 我有这个问题 \“解串器不具有映射到此合同的任何类型的知识\” 谷歌搜索后,我到达了这个职位 反序列化器不具有映射到此合同的任何类型的知识 答案在哪里,基类必须声明\“ KnownTypes \”,例如 [DataContract,KnownType(typeof(Subclass))...], 如果必须在父类[DataContract,KnownType(typeof(Subclass))]中声明它,这是否违反OO Design的原理,即父类不必了解子类? 正确的做法是什么?     
已邀请:
        序列化程序的设计方式是,如果序列化对象,则应该能够将其读回。如果您尝试序列化声明类型为\'Base \'的对象,但实际类型为\'Derived \'(请参见下面的示例),则希望从序列化对象中读回一个实例。 \'Derived \',您需要以某种方式注释实例不属于所声明实例的XML。
[DataContract]
public class MyType
{
    [DataMember]
    public object obj = new Derived();
}
该类型的序列化版本看起来类似于以下XML:
<MyType>
  <obj actualType=\"Derived\">
    <!-- fields of the derived type -->
  </obj>
</MyType>
反序列化类型时,序列化程序将查看\“ actualType \”(不是实际名称)属性,并且它将必须找到该类型,对其进行初始化并设置其属性。让序列化程序(在Silverlight中使用的是受信任的程序集,并且比普通用户代码具有更多的“权限”)创建任意类型是一个潜在的安全问题,因此这是限制类型的原因之一可以反序列化。并且基于序列化器的设计(如果我们可以序列化它,我们应该能够对它进行反序列化),则序列化也由于这个原因而失败。 另一个问题是,序列化的数据通常用于在不同的服务,不同的计算机以及可能使用不同的语言之间进行通信。您有可能(通常是这种情况)在客户端的命名空间中有一个类,该类与服务器端的类具有相似的数据协定,但是它们具有不同的名称和/或位于不同的命名空间中。因此,在这种情况下,仅在\“ actualType \”属性中添加CLR类型名称也不起作用([KnownType]属性可帮助serialzier将数据协定名称/名称空间映射到实际CLR类型)。此外,如果您正在使用其他语言/平台(即Java)与服务进行通讯,则CLR类型名称甚至都没有意义。 在帖子http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,a3775eb1-b441-43ad-b9f1-e4aaba404235.aspx中提供了另一个更详细的说明-它讨论的是[ServiceKnownType]而不是[KnownType] ,但原理相同。 最后,关于您的问题:是否违反了面向对象原则?是的,这个原则被打破了,要付出代价才能失去分布式(面向服务)应用程序中客户端和服务之间的耦合。     
        是的,它违反了面向对象设计的原理。这是因为SOA是关于共享合同(服务ABC中的C)而不是类型,而OO是关于类型层次结构。这样想,服务的客户甚至可能不是用OO语言,而是仍可以应用SOA原则。如何在服务器端完成映射是一个实现问题。     

要回复问题请先登录注册