我们大多数人都知道,WCF 不支持“面向对象”意义上的继承。话虽如此,有一些解决方法,但它们会产生开销。其中一些解决方法包括 KnownTypes 和 ServiceKnownTypes。为了简化跨线路的消息传递过程并保持性能,我正在考虑使用“数据传输对象”。我已经在“实体类库”和测试库中测试了这些对象,并遵循了两个独立的 CLR 继承结构。下面是每个的简化表示:
第一种情况:
这种情况下,BookDTO 继承自 Book 类所继承的同一个 IBook 接口。从 Book 到 BookDTO 没有“直接”继承。
第二种情况:
第二种情况允许 BookDTO 直接从 Book 和 IBook 继承。这似乎是最灵活的结构,因为它将支持面向对象的代码,以便在需要时通过直接转换在 Book 和 BookDTO 之间实现松散耦合和可互换性。此外,与 IBook 接口一样,Book 也有一个逻辑父级。但是,明显的问题是这种情况会在 Visual Studio 中引发警告,因为隐式包含的接口成员的属性上的 WCF DataMemberAttribute 属性的任何实现都将隐藏父类属性。
我的问题:如果我的意图是允许在类库中正确继承,同时通过“数据传输对象”支持简化的消息传递基础架构,是否建议创建获取和设置父属性的本地版本的属性?请参阅下面的代码参考:
[DataContract(Name="BookDTO")]
class BookDTO: Book, IBook
{
[DataMember(Name="Author")]
string Author { get { return base.Author; } set { base.Author = value; } }
[DataMember(Name = "Publisher")]
string Publisher { get { return base.Author; } set { base.Author = value; } }
[DataMember(Name = "Id")]
int Id { get { return base.Id; } set { base.Id = value; } }
[DataMember(Name = "Name")]
string Name { get { return base.Name; } set { base.Name = value; } }
}
确实,这会引发编译器警告 CS0108(2 级警告)。我可以通过使用“新”关键字来克服这个问题。我的问题是,考虑到面向对象代码的逻辑继承,以上两种情况下的结构是可取的吗?为序列化扁平化类层次结构的能力有其好处,但我需要将 DataContractAttribute 和 DataMemberAttribute 添加到每个属性。
我这样做的原因是有几种自定义类型将在“Book”和“BookDTO”的实际生产代码中进行数组序列化。此外,我期待不止一种类型的产品,但“产品”类将保持抽象,永远不应该单独实现。
让我知道我对案例二的直觉是否正确,或者如果 BookDTO 仅源自 IBook 接口,我是否需要考虑“无警告”结构。
附加说明:我喜欢案例二的结构,因为它支持从 BookDTO 向上转换到 Book ... (Book)BookDTO。在 ASP.NET 下的 OOP 模型中,向上转换比支持以下转换结构要便宜得多(几乎免费):(Book)(IBook)BookDTO ...如果开发人员使用此实体库,这将更加昂贵决定在对象之间进行排序和转换。此外,强制转换需要返回到根接口。这只是让我有点畏缩......