22

I am using C# 8 with .NET framework 4.8

I'm currently guarding against a potential string that can be null with IsNullOrWhitespace (same problem with IsNullOrEmpty) , but the compiler is still complaining :

public MyImage? LoadImage(string? filename)
{
    if (string.IsNullOrWhiteSpace(filename))
    {
        return null;
    }
    return OtherMethod(filename); // here : warning from Visual Studio
}

// signature of other method :
public MyImage OtherMethod(string filepath);

Hint / warning from VS : 'filename' may be null here.

currently, I have workarounds to make the compiler understand :

  • use null forgiving operator filename!
  • disable warning by using #pragma warning disable CS8604 // Possible null reference argument.
  • add another check for null if(string == null || string.IsNullOrWhitespace(filename))

But none of the seems satisfactory, mainly because I'll need to repeat the workaround for each call to IsNullOrEmpty.

Is there any other way to tell the compiler that IsNullOrEmpty effectively guards against null ?

Pac0
  • 21,465
  • 8
  • 65
  • 74
  • Maybe this link will help: [https://github.com/dotnet/roslyn/issues/37995](https://github.com/dotnet/roslyn/issues/37995) – Paul Adam Feb 25 '20 at 10:04
  • C# 8.0 is only supported on platforms that implement .NET Standard 2.1, not .NET framework... That said, if you define the DoesNotReturnIf attribute yourself then you can define an Assert method of your own and use that one instead. – Julien Couvreur Mar 02 '20 at 00:38
  • 2
    @JulienCouvreur That's not correct: https://stackoverflow.com/a/57020770/2729609 C#8 is available for .Net-Framework. – Sebastian Schumann Mar 05 '20 at 06:55
  • 1
    @SebastianSchumann I'm sorry, but the summary that is provided correctly concludes that "The C# 8/.NET Framework combination is not officially supported by Microsoft.". Note that "supported" is not the same thing as "was not disabled and can still mostly work for adventurous folks". – Julien Couvreur Mar 06 '20 at 14:54
  • 1
    @JulienCouvreur yeah, right. At least it's partially supported! But the precise Attributes that are supposed to help with my issue are available only in "full support", i.e. with .NET Core 3 – Pac0 Mar 06 '20 at 15:10

1 Answers1

10

If you don't have .net standard 2.1 or .net core 3, the IsNullOrEmpty is not nullable ready. So, I would create an extension method for this:

#nullable enable
public static class StringExt {
    public static bool IsNullOrEmpty([NotNullWhen(false)] this string? data) {
        return string.IsNullOrEmpty(data);
    }
}
#nullable restore

You also need to activate NotNullWhen attribute like this:

namespace System.Diagnostics.CodeAnalysis
{
    [AttributeUsage(AttributeTargets.Parameter)]
    public sealed class NotNullWhenAttribute : Attribute {
        public NotNullWhenAttribute(bool returnValue) => ReturnValue = returnValue;
        public bool ReturnValue { get; }
    }
}
ims1234
  • 183
  • 1
  • 7
  • What do you mean by "activate NotNullWhen attribute"? From the snippet it looks like you're just re-declaring the attribute. – killswitch Aug 23 '22 at 12:36
  • The "NotNullWhen" attribute is not included in .NET Framework 4.8, that's why they're declaring it. – Joshua VdM Aug 30 '22 at 15:35
  • Brilliant! Didn't know this is possible with NetFramework48. This lead me to the fact that this can also be done with the CallerArgumentExpressionAttribute which can also be helpful, e.g. in Guards. – Lumo Jul 06 '23 at 12:41