10

I have a method which never returns a null object. I want to make it clear so that users of my API don't have to write code like this:

if(Getxyz() != null)
{
  // do stuff
}

How can I show this intent?

Jason Plank
  • 2,336
  • 5
  • 31
  • 40
StackUnderflow
  • 24,080
  • 14
  • 54
  • 77
  • Besides, there's no way to know if you could even return a non-null object in the first place (unless it's a struct) Maybe you want to return a struct? – Trap Jan 27 '09 at 18:38
  • Now standardized as `Contract.Ensures(Contract.Result() != null)` in [Code Contracts - postconditions](https://learn.microsoft.com/en-us/dotnet/framework/debug-trace-profile/code-contracts#postconditions) in [System.Diagnostics.Contracts namespace](https://learn.microsoft.com/en-us/dotnet/api/system.diagnostics.contracts). From the first link above, I get [this link to download](https://marketplace.visualstudio.com/items?itemName=RiSEResearchinSoftwareEngineering.CodeContractsforNET). – ToolmakerSteve Apr 17 '20 at 19:34

9 Answers9

10

Unfortunately there is no way built in to C#

You can document this fact, but this won't be automatically checked.

If you are using resharper, then it can be set up to check this properly when the method is marked with a [NotNull] attribute.

Otherwise you can use the Microsoft Contracts library and add something similar to the following to your method, but this is quite a lot of extra verbiage for such a simple annotation.

Contract.Ensures(Contract.Result<string>() != null)

Spec# solved this problem by allowing a ! after the type to mark it as a non-null type, eg

string! foo

but Spec# can only be used to target .NET2, and has been usurped by the Code Contracts library.

Jonathan
  • 330
  • 1
  • 10
Oliver Hallam
  • 4,242
  • 1
  • 24
  • 30
  • Uh, but this is wrong...you can guarantee that a method does not return null. See any of the other answers... – Robert P Jan 27 '09 at 20:13
  • 3
    Using a struct does not help if you want to return a non-null string. You could return a not-null struct containing a string that may be null, but how is that any better? – Oliver Hallam Jan 29 '09 at 12:34
  • the syntax is wrong on your Contracts example. The `Result` should be a method call: `Contract.Result()` – porges May 09 '10 at 07:08
  • Now standardized as `Contract.Ensures(Contract.Result() != null)` in [Code Contracts - postconditions](https://learn.microsoft.com/en-us/dotnet/framework/debug-trace-profile/code-contracts#postconditions) in [System.Diagnostics.Contracts namespace](https://learn.microsoft.com/en-us/dotnet/api/system.diagnostics.contracts). – ToolmakerSteve Apr 17 '20 at 19:31
6

Unless you are using a type based on System.ValueType, I think you are out of luck. Its probably best to document this clearly in the XML/metadata comment for the function.

Jason Jackson
  • 17,016
  • 8
  • 49
  • 74
2

I don't know that there is a best practice for doing so from an API as I would still program defensively and check for null as the consumer. I think that this is still the best practice in this case as I tend to not want to trust other code to always do the right thing.

Brawndo
  • 489
  • 4
  • 10
2

The only type-checked way to ensure that a C# object never returns null is to use a struct. Structs can have members that contain null values, but can never be null themselves.

All other C# objects can be null.

Example code:

public struct StructExample
{
    public string Val;
}

public class MyClass
{
    private StructExamle example;

    public MyClass()
    {
        example = null; // will give you a 'Cannot convert to null error
    }

    public StructExample GetXyz()
    {
        return null; // also gives the same error
    }
}

The above example will not compile. If using a struct is acceptable (it becomes a value type, gets passed around on the stack, can't be subclassed) then this might work for you.

Robert P
  • 15,707
  • 10
  • 68
  • 112
  • Note that structs pass *by value* by default, while classes pass *by ref* by default. The difference is that the *contents* of the struct is dumped onto the stack when passing, while for classes only a *reference* is dropped on the stack, allowing you to interact with the original object rather than a new copy. This can be overridden by using the "ref" keyword, but then you 1) have to remember to use it every place that you don't want a copy, and 2) it can be null again, which was what you were trying to avoid in the first place. – Thought Apr 10 '14 at 22:02
1

I like to think of it the other way around: if my function could return a null value I better make sure that the function's user knows about it.

Joel Coehoorn
  • 399,467
  • 113
  • 570
  • 794
0

If your users have your source code using a standard design by contract API like: http://www.codeproject.com/KB/cs/designbycontract.aspx can make things clear.

Otherwise your best bet is through documentation.

JoshBerke
  • 66,142
  • 25
  • 126
  • 164
0

Either document it well (maybe with .NET standard documentation system) or you have to use some Contract API. Here are some: Link http://www.codeproject.com/KB/cs/designbycontract.aspx

Glorfindel
  • 21,988
  • 13
  • 81
  • 109
Stefano Driussi
  • 2,241
  • 1
  • 14
  • 19
0

You could include a Debug.Assert() method. While this certainly won't enforce the condition, it should make it clear (along with documentation) that a null value isn't acceptable.

Otis
  • 992
  • 3
  • 12
  • 22
0

Document it and provide the source code.

Tundey
  • 2,926
  • 1
  • 23
  • 27