David
David

Reputation: 2556

Fixing "CS8762: Parameter must have a non-null value when exiting with 'true'."

How do I tell the compiler that my out variable is assigned the moment I am returning with true?

private static bool Resolve(IEnumerable<Type> testClasses, string requestedTestClass, [NotNullWhen(true)] out Type? resolvedTestClass)
{
  resolvedTestClass = null;
  List<Type> matches = new();
  List<string> options = new();

  // determine matches
  foreach(var testClass in testClasses)
  {
    options.Add($"{testClass.Name} from {testClass.Namespace}");
    if (testClass.Name.StartsWith(requestedTestClass))
    {
      matches.Add(testClass);

      // remember the first match
      if (matches.Count == 1)
      {
        resolvedTestClass = testClass;
      }
    }
  }

  if (matches.Count == 1)
  {
    return true;
  }

  // outputting here all matches and all options if more than one match was found

  return false;
}

The compiler says that the parameter resolvedTestClass must have a non-null value when exiting with 'true'. Since it's the same condition it is true, but the compiler just cannot know.

I admit there are better ways to implement the functionality, so let's take this just as an example and focus on the central question which is: Is there a way to tell the compiler (eg. with placing some attribute(s) somewhere) that "all is alright"?

Upvotes: 1

Views: 500

Answers (1)

Caius Jard
Caius Jard

Reputation: 74615

Minimally, it looks like you can do away with the lists too..

    private static bool Resolve(IEnumerable<Type> testClasses, string requestedTestClass, [NotNullWhen(true)] out Type? resolvedTestClass)
    {
      resolvedTestClass = null;
      bool multiple = false;

      // determine matches
      foreach(var testClass in testClasses)
      {
        if (testClass.Name.StartsWith(requestedTestClass))
        {
          multiple = (resolvedTestClass != null); //have we already seen a match?
          if(multiple) break;                     //don't need to check any more to know we have multiple
          resolvedTestClass = testClass;          //only set once; the first time
        }
      }

      return !multiple && resolvedTestClass != null;
    }

It doesn't actually complain if you remove the && resolvedTestClass != null, but...

Upvotes: 1

Related Questions