我需要创建一些DTO类来跨WCF传输业务对象。
由于这些只是没有功能的数据包,有什么理由我不能只使用字段,还是有充分的理由将它们作为属性正确公开?
//fields
[DataContract]
class CustomerDTO
{
[DataMember] public int Id;
[DataMember] public string Name;
}
//or properties?
[DataContract]
class CustomerDTO
{
[DataMember] public int Id { get; set; }
[DataMember] public string Name { get; set; }
}
答案 0 :(得分:17)
如果我可以避免的话,我主要支持带有只读字段的不可变DTO:
public class CustomerDTO
{
public CustomerDTO(int id, string name)
{
Id = id;
Name = name;
}
public readonly int Id;
public readonly string Name;
// Override Equals and GetHashCode as well...
}
不可变的记录具有很多优点,例如结构相等性,这使自动测试断言的编写更加容易。也dispenses with the need to write and maintain separate Test Data Builders。
但这取决于序列化器。 JSON.NET可以处理不可变的记录,但许多其他序列化器则不能。
对于那些处理公共字段的人,我更喜欢字段而不是属性,这仅仅是因为它更诚实。 automatically implemented read/write properties provide no encapsulation。
一些序列化程序坚持使用公共属性,而不序列化字段。如果是这种情况,则必须这样做。
老实说,考虑到我对此有多大的思考,这并不是让我彻夜难眠的东西,因为最终at the boundaries, applications aren't object-oriented。因此,OOD规则实际上并不真正适用于DTO。
答案 1 :(得分:4)
由于这些只是没有功能的数据包,我有什么理由不能只使用字段
这里没有针对公共领域的强烈论据。但是要意识到这只是因为DTO中没有逻辑(行为),因此封装的正常参数不成立。
我仍然会喜欢属性,但这里并不是必需的。
答案 2 :(得分:1)
DataMember
属性将同时适用于公共字段和属性,因此任何一种都可以。但是,我建议坚持使用属性。
特别是,如果您使用的是StyleCop,那么您将会破坏rule SA1401。
此规则存在的原因并不适用于您的情况,但如果您将StyleCop验证作为持续集成服务器上的构建的一部分运行,则仍然是一个维护问题。
答案 3 :(得分:1)
您可以使用其中之一。由于它不会影响性能,因此如果遇到某些序列化框架或与公共字段不兼容的类似框架,您将更安全地使用属性。
请注意,即使您在服务端使用公共字段,WCF代理生成也会在客户端使用公共属性及其支持私有字段创建这些DTO。如果您不希望这样,您需要在服务和客户端之间共享DTO库。
答案 4 :(得分:1)
与其他我没有看到的字段相比,这里的属性有两个优点。
我认为默认行为应该是更安全的选择。对于字段,默认行为允许可变性,这是更危险的选择。必须添加关键字readonly
以使字段不可变(在构造函数之外)。相反,auto属性的默认状态是不可变的。必须添加语法set;
才能使属性可变(在构造函数之外)。
与字段不同,在Visual Studio中查看属性具有“代码镜头”,其中包括其引用计数。由于有了这些附加信息,我能够比字段更快地理解和重构属性。当然,可以使用Shift + F12在Visual Studio中搜索对诸如字段和属性之类的内容的引用,但这是一个额外的步骤,需要花费一些时间。此外,在极少数情况下,某些项目会包含多个目标。这将使Shift + F12搜索结果更难以使用,因为每个目标都进行了搜索。在合同中,物业的“代码镜片”中给出的参考计数与项目目标的数量无关。
不过,为了直接回答问题,我更喜欢使用可变属性(并且没有显式构造函数),以确保我将使用序列化库中最幸福的快乐路径(在the answer of @ErenErsönmez中提到)
答案 5 :(得分:0)
我永远不会直接揭露领域,大多数公司都禁止在他们的标准中使用。实际上你完全扔掉了封装。 DTO是一种更复杂的东西的贫血表征,这是一个奇怪的例子,因为它们的属性无论如何都会破坏封装。就个人而言,我会使用这些属性,就像他们在那里一样。它还允许您实现“脏”功能等,如果您需要直接调整字段而不是那么容易。