【问题标题】:Null vs Value Not Set空值与未设置值
【发布时间】:2009-05-11 07:37:02
【问题描述】:

我们编写了一个 Web 服务,它使用一个简单的实体转换器将 DTO 的值映射回“真实的”服务器端业务对象。作为本次练习的一部分。我们遇到了显式设置 null 值未设置 值的客户端之间的“有趣”区别。

问题本质上是我们想要在真实的业务对象上设置一个默认值如果客户端没有显式设置一个值,但是使用标准的可空类型没有办法判断一个客户明确表示“将此设置为空”或只是不设置它。

这里的解决方案显然是某种“标志”。

在业务对象中,我们可以使用在属性设置器中设置的私有“IsDirty”标志在内部跟踪字段的状态,但 DTO 只真正指定了一个接口,因此这意味着将这些数据公开给公众。这留下了许多实现选项。语言是 C#(所以是静态类型的)所以...

  1. 我们可以在每个属性上公开一个“IsSet”标志吗?
  2. 我们可以将每个属性公开为具有 .Value 和 .IsSet 属性的类吗? 等等等等。

将如何选择在数据合同上公开这些“标志”? 您认为最佳实践是什么?

对此的任何意见将不胜感激。

【问题讨论】:

    标签: wcf design-patterns datacontract


    【解决方案1】:

    为每个属性值使用一个类比为每个属性声明一个布尔值更具可扩展性。它还可以让您选择哪些属性可以留空和/或设置为 null。

    【讨论】:

      【解决方案2】:

      您可以编写一个用数据包装标志的类:

      public class DtoData<T> 
      {
        T data;
        bool IsSet { get; private set; }
        T Data 
        { 
          get { return data; }
          set { data = value; IsSet = true; } 
        }
      }
      
      
      public class XyzDto 
      {
        // only private setters, initialize in constructor
        DtoData<int?> SomeInt { get; private set; }
        DtoData<string> SomeString { get; private set; }
      }
      

      这有一些缺点。例如,您的所有数据都包装在引用类型中,因此对 DtoData 的引用仍然可能为空,您需要在构造函数中创建它们。而且很难让值只能在内部或受保护的情况下访问。


      就个人而言,我会尽量避免这个问题。为什么“未定义”实际上应该存在?您是在发送差异、不完整的 Dto,还是来自哪里?过滤器可能会出现此问题,如果您将字段过滤为 null 或根本不过滤,则需要有所不同。但是对于这样的场景,你还是需要一个特殊的“field-filter”类。

      【讨论】:

        【解决方案3】:

        一般来说,您在这里谈论的是一个默认值,它不同于用户可以设置的任何值。因此,只需指定即可;将默认值设置为不在用户可以设置的允许值范围内的值。这样,如果该值是默认值,则您知道它尚未设置;如果值不是这个值,你就知道用户已经修改了它。仅仅因为用户可设置的值之一是 null 似乎会让你失望;只需将其视为一组用户可设置值之一;使变量的整个范围成为一个稍大的集合,并具有一个额外的默认值。这应该可以解决您的问题。

        【讨论】:

          【解决方案4】:

          我以前遇到过这个确切的问题。您可以通过在 DTO 的构造中引入一些默认值来解决此问题,但这并不理想。我已经写了更详细的博客here,它可能会帮助人们进一步了解这个问题。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2022-11-04
            • 1970-01-01
            • 1970-01-01
            • 2021-04-10
            • 2010-09-23
            • 2018-06-18
            相关资源
            最近更新 更多