Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use of unassigned parameter compiler error, for a variable received from a function out parameter?

Today I encountered (by mistake) a weird compiler error and I don't understand the reason for it (compiler issue maybe?). .Net Framework 4.0 and Visual Studio 2019 if that matters.

The exact error is "Use of unassigned local variable 'value'" at the if after the TryParse. The code compiles fine if I use s or I cast d.s to string.

using System;
using System.Dynamic;

namespace TestConsoleApp
{
    static class Program
    {
        static void Main(string[] _)
        {
            string s = "1";

            dynamic d = new ExpandoObject();
            d.s = s;

            if (d.s != null && int.TryParse(d.s, out int value))
            {
                if (value == 1)
                {
                    Console.Out.WriteLine("OK!");
                }
            }
        }
    }
}
like image 593
mBardos Avatar asked Oct 14 '22 22:10

mBardos


1 Answers

On the first sight it looks like a compiler bug. If you remove the d.s != null-check, which is unnecessary anyway, it will compile fine. But i think this comment here explains it: https://github.com/dotnet/roslyn/issues/39489#issuecomment-546003060


Unfortunately, this is not a bug, this is caused by the existence of true/false operators in C#.

You can define a type that would evaluate to true under left operand of && expression without evaluating the right operand of &&, something like this:

class C {
  public static U operator==(C c, C d) => null;
  public static U operator!=(C c, C d) => null;
}

class U {
  public static U operator &(U c, U d) => null;
  public static implicit operator U(bool b) => null;
  public static bool operator true(U c) => true;
  public static bool operator false(U c) => false;
    
  public void M(C c, object o) {
    if (c != null && o is string s) {
      s.ToString(); // CS0165: Use of unassigned local variable 's'
    }
  }
}

When working with values of type dynamic, C# has no static information about the type and it's overloaded operators, so it assumes the "worse" - type like U in example above.

like image 64
Tim Schmelter Avatar answered Oct 20 '22 03:10

Tim Schmelter