Question

How do I avoid Dereference of a possibly null reference?

(Using ASP.NET Core 7 and VS2022)

I have a utility function that I'm bringing over from an old .NET project:

The original looked like this:

public static string WriteString(object str)
{
    if (str == null)
        return "";
    else
        return str.ToString().Trim();
}

I converted it to this:

public static string WriteString(object str)
{
    object s = str ?? "";
    return s.ToString().Trim();
}

But I'm still getting the "Dereference of a possibly null reference" warning. Am I missing something? My variables can't possibly be null, because I'm using the null coalescing operator. So what's bothering VS?

 2  111  2
1 Jan 1970

Solution

 3

In Visual Studio, if you navigate into Object class definition, you will see the signature of .ToString()

    //
    // Summary:
    //     Returns a string that represents the current object.
    //
    // Returns:
    //     A string that represents the current object.
    public virtual string? ToString();

string? causes str.ToString() to be evaluated to string? and .Trim() can only operate on non nullable string. Technically, you will never get an error, but you might do an extra null check for str.ToString() != null

or you might do str.ToString()!.Trim() just to satisfy the compiler

.NET Framework projects do not produce this warning because signature for .ToString() is different

public virtual string ToString() => this.GetType().ToString();
2024-07-04
Yehor Androsov

Solution

 2

You could do like this:

public static string WriteString(object str)
{
    return s?.ToString().Trim() ?? "";
}

If any of the possible objects in your project might return null as a result of the ToString function, you can add a check for that too, to avoid calling Trim() on a null object:

public static string WriteString(object str)
{
    return s?.ToString()?.Trim() ?? "";
}
2024-07-04
Lex W.

Solution

 2

As other's have stated Object.ToString() returns string? which could return a null value.

Here's the documentation: Object.ToString

And the actual implementation:

/// <summary>Returns a string that represents the current object.</summary>
/// <returns>A string that represents the current object.</returns>
public virtual string? ToString()
{
    // The default for an object is to return the fully qualified name of the class.
    return GetType().ToString();
}

What you should probably do is check for null at each step falling resorting to "" when any step returns a null value.

public static string WriteString(object str) =>
    str?.ToString()?.Trim() ?? "";
Caveat for .NET Framework

Interestingly the .NET Framework version of `Object.Tostring() method signature is different

public virtual string ToString ();

If you were targetting .NET Framework then your code would not have produced any warnings at all.

2024-07-04
phuzi

Solution

 1

Instead of rewriting all your code to get rid of those warnings, you could also switch off specific warnings in Visual Studio. See this Microsoft article.

A list of all nullable warnings can be found here.

2024-07-04
Theo

Solution

 0

And finally (maybe) create an extension and use a better name:

public static string ToStringTrimmedOrEmpty(this object obj) 
      => obj?.ToString()?.Trim() ?? string.Empty;
    
2024-07-04
decius