15

我需要创建一些 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; }
}
4

6 回答 6

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...
}

不可变记录有很多优点,例如结构相等,这使得自动化测试断言更容易编写。它还免除了编写和维护单独的测试数据构建器的需要

不过,这取决于序列化程序。JSON.NET 可以处理不可变记录,但许多其他序列化程序不能。

对于那些处理公共字段的人,我更喜欢字段而不是属性,仅仅是因为它更诚实;自动实现的读/写属性不提供封装

一些序列化程序坚持使用公共属性,并且不序列化字段。如果是这样的话,你就必须顺其自然。

老实说,考虑到我为此付出了多少思考,这并不是让我夜不能寐的事情,因为最终,在边界上,应用程序不是面向对象的。因此,OOD 的规则并不真正适用于 DTO。

于 2020-02-25T20:06:53.337 回答
6

由于这些只是没有功能的数据包,有什么理由我不能只使用字段

这里没有反对公共领域的强烈论据。但是请意识到这只是因为 DTO 内部没有逻辑(行为),因此封装的正常参数不成立。

我仍然更喜欢属性,但在这里它们并不是必需的。

于 2012-05-31T10:02:49.173 回答
3

你可以使用任何一个。由于它不会影响性能,因此如果遇到一些不适用于公共字段的序列化框架或类似框架,则使用属性会更安全。

请注意,WCF 代理生成将在客户端使用公共属性及其支持的私有字段创建这些 DTO,即使您在服务端使用公共字段也是如此。如果您不希望这样,您需要在服务和客户端之间共享一个 DTO 库。

于 2012-05-31T10:34:10.823 回答
1

DataMember属性将与公共字段和属性一起使用,因此两者都是可能的。但是,我建议坚持使用属性。

特别是,如果您使用 StyleCop,那么您将违反规则 SA1401

此规则存在的原因并不真正适用于您的情况,但如果您在持续集成服务器上运行 StyleCop 验证作为构建的一部分,它仍然是一个维护问题。

于 2012-05-31T10:09:06.960 回答
1

这是我没有看到其他人提到的属性相对于字段的两个优点。

  1. 语法中的摩擦正确匹配功能

我认为默认行为应该是更安全的选择。对于字段,默认行为允许可变性,这是更危险的选择。readonly必须添加关键字以使字段不可变(在构造函数之外)。相反,自动属性的默认状态是不可变的;set;必须添加语法才能使属性可变(在构造函数之外)。

  1. Visual Studio 的 Code Lens中给出的引用计数

与字段不同,在 Visual Studio 中查看属性有一个“代码镜头”,其中包括其引用计数。由于这些附加信息,我能够比字段更快地理解和重构属性。当然,可以使用 Shift+F12 在 Visual Studio 中搜索对字段和属性等内容的引用,但这是一个需要时间的额外步骤。此外,在极少数情况下,一些项目包括多个目标。这使得 Shift+F12 搜索结果更难使用,因为对每个目标都执行了搜索。在合同中,属性的代码 Len 中给出的引用计数与项目目标的数量无关。

结论

不过,为了直接回答这个问题,我更喜欢使用可变属性(并且没有显式构造函数),以确保我将在序列化库中使用最快乐的路径(@ErenErsönmez 的答案中提到了这一点)。

于 2020-03-02T02:50:04.393 回答
0

我永远不会直接公开字段,大多数公司在他们的标准中都禁止这样做。实际上,您完全抛弃了封装。DTO,作为更复杂事物的贫乏表示,是一个奇怪的情况,因为它们的属性几乎打破了封装。就个人而言,我会使用这些属性,因为这就是它们的用途。如果您需要,它还可以让您实现“脏”功能等,如果您直接调整字段,这并不容易。

于 2012-05-31T10:00:10.870 回答