Home > Software design >  Use of unassigned local variable in out parameter
Use of unassigned local variable in out parameter

Time:05-16

I am having a problem with C# giving the "Use of unassigned local variable" compile error. What am I missing?

// returns generic result of a function with error message 
// why the function failed
public class Result
{
    public bool isSuccess = true;
    public string errorMessage = string.Empty;

    public static implicit operator bool(Result r)
    {
        return r.isSuccess;
    }

    public static Result operator &(Result a, Result b)
    {
        return !a.isSuccess ? a : b;
    }

    public static Result operator |(Result a, Result b)
    {
        if (a.isSuccess)
        {
            return a;
        }
        if (b.isSuccess)
        {
            return b;
        }
        return new Result
        {
            isSuccess = false,
            errorMessage = $"{a.errorMessage}\nOut{b.errorMessage}"
        };
    }

    public static bool operator false(Result a)
    {
        return !a.isSuccess;
    }

    public static bool operator true(Result a)
    {
        return a.isSuccess;
    }
}

static Result Func1(int nIn, out int nOut)
{
    nOut = nIn   1;
    return new Result();
}

private static void Main(string[] args)
{
    var resultA =
        Func1(0, out var a1) &&
        Func1(a1, out var a2); // compiles fine

    var resultB =
        Func1(0, out var b1) &&
        Func1(b1, out var b2) &&
        Func1(b2, out var b3); // Use of unassigned local variable 'b2'
}

CodePudding user response:

I think this may be a bug in the compiler - I'd personally expect b2 to be definitely assigned there. The spec for definite assignment is pretty hairy though, so I'm not going to try to prove it one way or another right now. It's possible that the rules aren't "clever" enough to work out that the only way that (x && y) is true is if both x and y are evaluated, and so in (x && y) && z, z should be able to rely on both x and y having been evaluated.

However, it's fairly easy to work around, just with an extra pair of parentheses:

var resultB =
        Func1(0, out var b1) &&
        (Func1(b1, out var b2) && Func1(b2, out var b3));
  •  Tags:  
  • c#
  • Related