C#:Sane替代属性中的可选参数?

时间:2010-11-06 22:42:22

标签: .net-3.5 c#-3.0 properties

给定:具有SomeNumber属性的类,内部可以为null(即int?),但在外部,您通常不希望处理该特殊情况,并假装他们从零开始。到目前为止,我们总是返回一个不可为空的版本,即int。我想添加一个可选版本的选项。

最简单的变体:两个属性。效果很好,但不幸的是,这个课程有很多冗余的选项。外部代码:

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

内部脏但外部很好的变体:带有可选参数的属性。我还没有发现如何在C#中做到这一点; .NET Reflector似乎忽略了错误的代码。在VB.NET中,它看起来像这样:

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.

缺点之一: * C#实现是如此丑陋.NET Reflector似乎甚至不知道如何做到, *我发现参数化属性的一般概念值得怀疑, *在非可空的示例中,返回类型与属性的实际行为不匹配 - 编译器现在认为可以null,但实际上不能。{ / p>

还有其他想法吗?

2 个答案:

答案 0 :(得分:3)

听起来你正试图过度设计你的课程。属性为null,或者不是,并且客户端检查空值不是负担。我觉得理解你的API是一种负担,对我来说这听起来像是:'这个属性永远不会为空。除非你检查它是否真的是空的。咦?

此外,尝试隐藏空值通常是一个坏主意,因为它会隐藏程序中的错误。

答案 1 :(得分:1)

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

如果您不希望类的用户意识到您的字段内部可能为null,那么如果您控制属性的实现,则非常简单。将属性的支持字段定义为int?类型,但将属性类型保留为int

例如:

private int? _someNumber = null;

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

现在,在内部,您始终可以访问_someNumber.HasValue以检查是否已设置值。

但是,如果你说“我想添加一个可以使用可以为空的版本的选项。”,如果你想要一种方法向你的客户公开,是否{{1}有一个值,那么你有几个选择:

  • 公开SomeNumber
  • 等财产
  • bool SomeNumberHasValue的类型更改为SomeNumber
  • 添加第二个属性int?,其返回类型为SomeNumberNullable

但是,单个属性有时无法返回int?并返回int

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

int?

实际上,您正在做很多工作,以便让客户端轻松处理空检查,而不会隐藏值为null的事实。有什么好处?