开发者

C#: Sane alternative to optional parameter in property?

Given: a class with properties like SomeNumber that, internally can be null (i.e. int?), but externally, you typically don't want to handle that special case, and pretend they start out as zero. So far, we're always returning a non-nullable version, i.e. int. I'd like to add an optio开发者_Go百科n to have a nullable version.

The easiest variant: Two properties. Works great, but unfortunately clutters the class with lots of largely redundant options. External code:

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

The internally dirty, but externally nice variant: A property with an optional parameter. I haven't yet found out how to do this in C#; .NET Reflector seems to be omitting incorrect code. In VB.NET, it looks like so:

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

External code:

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

Among the disadvantages: * C# implementation is so ugly .NET Reflector doesn't even seem to know how to do it, * I find the general notion of parameterized properties questionable, * In the non-nullable example, the return type doesn't match the actual behavior of the property — the compiler now thinks it can be null, but it really can't.

Any other ideas?


It sounds like you are trying to over-design your class. A property is null, or it is not, and it's not a burden for the client to check for nulls. I would find it a burden to understand your API, which to me sounds something like: 'This property is never null. Unless you check to see if it really is null.' Huh?

Also, trying to hide null values is generally a bad idea because it hides errors in your program.


Properties cannot have parameters in C#, so if you want to use property syntax you'll need two properties with different names.

If you don't want users of your class to be aware of the fact that internally your field could be null, its pretty straightforward if you control the implementation of your property. Define the backing field of your property to be of type int?, but leave the type of your property as int.

For example:

private int? _someNumber = null;

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

Now, internally, you can always access _someNumber.HasValue to check if a value has been set or not.

However, when you say "I'd like to add an option to have a nullable version.", if you do want a way to expose to your client whether or not SomeNumber has a value then you have a few options:

  • Expose a property like bool SomeNumberHasValue
  • Change the type of SomeNumber to int?
  • Add a second property SomeNumberNullable that has a return type of int?

However, a single property cannot sometimes return int and return int? other times.

Another option would be to use a method to access the value, like so:

public int? GetSomeNumber(bool canReturnNull)
{
    if (canReturnNull)
        return _someNumber;

    return _someNumber.HasValue ? _someNumber.Value : 0;
}

In effect, you're doing a lot of work to make it easy for your clients to handle a null check, without hiding the fact the value can be null. What's the benefit?

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜