0

I switched the Value Analysis Mode in Rider to Pessimistic to highlight every "Possible NullReferenceException" and in the example below, I have a warning on the "Languages[0]" part and I don't understand why since I initialize my collection right after declaring it.

It should not be null then.

I just tested on an empty project and I have the same warning.

using System.Collections.Generic;

namespace ClassLibrary1
{
    public class Class1
    {
        public static string Current => Languages[0];

        public static readonly List<string> Languages = new List<string>
        {
            "en"
        };
    }
}

Is it a mistake made by ReSharper or did I missed something ?

Thanks.

cdauphin
  • 177
  • 10
  • I don't get this warning. What version of R# are you using? – Matthew Watson Jan 13 '20 at 15:49
  • I don't know how to get R# version on Rider (OS X). My Rider version is 2019.3 if that is relevant. – cdauphin Jan 13 '20 at 15:55
  • Mine is 2019.3.1, but I don't know if that's really going to make a difference. – Matthew Watson Jan 13 '20 at 15:59
  • That's not what Resharper warns about though - not without using [CanBeNull] attributes anyway. Resharper WILL warn if it thinks that you are dereferencing something that it thinks IS null, however. – Matthew Watson Jan 13 '20 at 16:00
  • @MatthewWatson - right... that would be an `IndexOutOfRange`. – Corak Jan 13 '20 at 16:01
  • 1
    @cdauphin Can you post a compilable repro console app? – Matthew Watson Jan 13 '20 at 16:02
  • @MatthewWatson Do you happen to know what difference the setting to "pessimistic" may play a role here? – Fildor Jan 13 '20 at 16:04
  • 1
    Yes, pessimistic will increase the number of warnings. – Matthew Watson Jan 13 '20 at 16:10
  • @MatthewWatson Thanks. Then what I was thinking of cannot be the case here. – Fildor Jan 13 '20 at 16:13
  • @MatthewWatson I edited the question with a complete class from an empty project I just created. I also tried to update & invalidate cache but I still have the warning. – cdauphin Jan 13 '20 at 16:14
  • I also get this warning when I turn on pessimistic analysis. It's a false warning for the code as written, though, because it is not possible for `Current` to be null when accessed from user code outside the class. (`'Languages` is readonly, so it can't be changed to non-null.) – Matthew Watson Jan 13 '20 at 16:22

2 Answers2

1

I think static properties are evaluated in order of appearance. Try to flip them in order to have first "Languages" and then "Current".

Antonio
  • 21
  • 1
  • 5
  • 1
    That's not the case for this code, because `Languages ` is a field that will be initialised before it is possible to access `Current`, which is a property. – Matthew Watson Jan 13 '20 at 15:52
1

Try this:

public static class Program
{
    public static readonly string Foo = Current;

    public static string Current => Languages[0];

    public static readonly List<string> Languages = new List<string>
    {
        "en"
    };

    public static void Main()
    {
        Console.WriteLine(Foo);
    }
}

SharpLab

Static members are initialized in the order they're declared. Foo is initialized before Languages is assigned, and so you see a NullReferenceException.

I guess that Resharper's being very pessimistic here, and only considering Current in isolation, regardless of whether there's actually another static member that might access it before Languages is initialised.


You could also have something diabolical like this, where the construction of Languages causes something to access Program.Current:

public static class Program
{
    public static string Current => Languages[0].Value;
    public static readonly List<Language> Languages = new List<Language>() { new Language() };

    public static void Main()
    {
        Console.WriteLine(Current);
    }
}

public class Language
{
    public string Value { get; } = Program.Current;
}

(It's a silly example, but it shows that it's perhaps harder for Resharper to prove that nothing accesses Program.Current before Program's type initializer has finished running, than you might expect).

canton7
  • 37,633
  • 3
  • 64
  • 77