简体   繁体   中英

Under what circumstances should `object.ToString()` return null?

.Net Core defines object.ToString() as public virtual string? ToString(); public virtual string? ToString();

This means that code such as the following provokes a CS8602 "Dereference of a possibly null reference" warning:

object t = "test";
var s = t.ToString();
Console.WriteLine(s.Length); // Warning CS8602

This is easily fixed by writing s..Length or t.ToString();; , but my question is:

Under what circumstances would it ever be correct to return null from an implementation of object.ToString() ?


The answer would appear to be: "You should never return null from object.ToString()", which is fair enough - but that does raise another question, which is "in that case, why did Microsoft declare it as public virtual string? ToString(); "?


Aside:

Some comments below suggest that because an implementation could incorrectly return null, then the return value must be declared as string? .

If that was true, then why doesn't the same logic apply to ICloneable.Clone() , which is not declared as returning object? ?

And surely this logic would apply to every single interface method that returned a reference type? Any implementation of such a method (for example, ICustomFormatter.Format() ) in theory could return null - and thus the return value should be nullable. But they are not.


Having read the link provided by DavidG, I believe the discussion in that topic answers the question to my satisfaction:

https://github.com/dotnet/coreclr/pull/23466

I can't see a reason why one would want anything.ToString() to ever return null , but who knows?

Then, I think object.ToString() is defined as returning a string? for compatibility reason: this exists since v1 of .NET and was always defined as returning a string and a string being a reference type can be null. The 'modern' declaration simply states that: there is a possibility the returned string can be null.

And do remember that this string? thing is very recent and merely metadata: even if it was typed string (as it was in older versions), implementations could still manage to return null.

In other words, brand new APIs can (and should) make use of Nullable annotations however they want, but the re-typing of existing libraries has to respect what the libraries did.

I say re-typing because it's not really typing, just annotations indicating expected behavior. It's kind of similar to the way Typescript 'annotates' Javascript code: the underlying type system is still the old one.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM