代码之家  ›  专栏  ›  技术社区  ›  Sören Kuklau Keith Boynton

C 35;:属性中可选参数的合理替代?

  •  1
  • Sören Kuklau Keith Boynton  · 技术社区  · 14 年前

    给定:一个属性类似于某个数字的类, 内部 int? )但是在外部,你通常不想处理这种特殊情况,并假装它们从零开始。到目前为止,我们总是返回一个不可为空的版本,即。 int . 我想添加一个可为空版本的选项。

    两个属性。很好用,但不幸的是,这个类中有很多冗余的选项。外部代码:

    return myObject.SomeNumber; // Not nullable.
    return myObject.SomeNumber_Nullable; // Nullable.
    

    内部脏,但外部好的变种:

    Private _SomeNumber As Nullable(Of Integer)
    Public Property SomeNumber(Optional ByVal AllowNull As Boolean = False) As Nullable(Of Integer)
      Get
        If Not AllowNull AndAlso _SomeNumber Is Nothing
          Return 0
        End If
    
        Return _SomeNumber
      End Get
      Set(ByVal value As Boolean)
        _SomeNumber = value
      End Set
    End Property
    

    外部代码:

    return myObject.SomeNumber; // Not nullable.
    return myObject.SomeNumber(true); // Nullable.
    

    缺点包括: *我觉得参数化属性的一般概念有问题, *在不可为空的示例中,返回类型与编译器现在认为的属性的实际行为不匹配 可以 null ,但真的不行。

    还有其他想法吗?

    2 回复  |  直到 14 年前
        1
  •  1
  •   Nader Shirazie    14 年前

    属性在C#中不能有参数,因此如果要使用属性语法,则需要两个名称不同的属性。

    如果您不希望类的用户知道字段内部可能为空,那么如果您控制属性的实现,这非常简单。将属性的backing字段定义为 int? ,但将您的财产类型保留为 int .

    private int? _someNumber = null;
    
    public int SomeNumber { 
      get { return _someNumber.HasValue ? _someNumber.Value : 0; }
      set { _someNumber = value; }
    }
    

    现在,在内部,您可以随时访问 _someNumber.HasValue

    但是,当您说“我想添加一个选项,使版本为空。”,如果您 想让你的客户知道 SomeNumber 有一个值,则有几个选项:

    • bool SomeNumberHasValue
    • 更改类型 内景?
    • SomeNumberNullable 返回类型为 内景?

    但是,单个属性有时无法返回 内景 然后回来 其他时间。

    另一种选择是使用方法访问值,如下所示:

    public int? GetSomeNumber(bool canReturnNull)
    {
        if (canReturnNull)
            return _someNumber;
    
        return _someNumber.HasValue ? _someNumber.Value : 0;
    }
    

    实际上,您正在做大量工作,使您的客户机能够轻松地处理空检查,而不隐藏值可以为空的事实。有什么好处?

        2
  •  3
  •   tsimon    14 年前

    听起来你是在试图过度设计你的课程。属性是空的,或者不是空的,客户机不必检查空值。我会发现理解您的API是一个负担,对我来说,这听起来像是:“这个属性永远不为空。”。除非你检查它是否真的是空的?