The Safe
extension method can never return null, but the compiler seemingly isn't able to detect that. I think I read something about this being an intentional design decision for strings, but don't recall when or where. Can anyone explain how to fix this (i.e., help the compiler along) or explain why it's intentionally this way?
Foo? foo = null;
Bar bar = new();
// CS8601: Possible null reference assignment.
bar.NoNullsHere = foo?.Text().Safe();
// No error with the trailing exclamation point
bar.NoNullsHere = foo?.Text().Safe()!;
public static class StringExtensionMethods
{
public static string Safe(this string? obj) => obj is null ? string.Empty : obj!;
}
public class Foo
{
public string? Text() => "has a value, but could be null or empty";
}
public class Bar
{
public string NoNullsHere { get; set; } = string.Empty;
}
Edit: the "right associative" answer provided by @sweeper is correct - the Safe
method will not get invoked. Given that, is it possible to do what I set out to accomplish? I really prefer the syntax and intellisense support. Also, my actual implementation accepts other arguments to the Safe
method to optionally do things like surround the resulting string with some token (e.g., double quote).
bar.NoNullsHere = foo?.Text().Safe();
instead of either of these
bar.NoNullsHere = StringExtensionMethods.Safe(foo?.Text());
bar.NoNullsHere = foo?.Text() ?? string.Empty;
Edit 2: forgot to mention that @sweeper does provide a work around. The required parentheses are a little annoying, but better than the alternatives. Thanks all!
bar.NoNullsHere = (foo?.Text()).Safe();