The compiler complains that resultingThing
in the code below is being used before being assigned to.
private IEnumerable<IThing> FindThings(dynamic spec)
{
if (spec == null)
yield break;
IThing resultingThing;
if (spec.Something > 0 && dictionary.TryGetValue(spec.Something, out resultingThing))
yield return resultingThing;
else
// ...
}
Why does it claim this?
I have tried a different version of the method in which there are no yield usages (e.g. just return IEnumerable<IThing>
) but with the dynamic parameter, and I have tried a version of the method in which dynamic is not passed in (i.e. what we've done in prior versions of C#). These compile.
I appears to be a compiler bug (or limitation, if you prefer).
I reduced the minimal failing case to:
static private IThing FindThings(dynamic spec)
{
IThing resultingThing;
if ((null!=spec) && dictionary.TryGetValue(spec, out resultingThing))
return resultingThing;
return null;
}
Which gives the same compiler diagnostic, without involving member lookup on dynamics, nor iterator blocks.
For reference the mono compiler does not trip over that:
using System;
using System.Collections.Generic;
public static class X
{
public interface IThing { }
private static readonly IDictionary<string, IThing> dictionary = new Dictionary<string, IThing>();
static private IThing FindThings(dynamic spec)
{
IThing resultingThing;
if ((null!=spec) && dictionary.TryGetValue(spec, out resultingThing))
return resultingThing;
return null;
}
public static void Main(string[] s)
{
}
}
Compiling that:
dmcs -v -warnaserror -warn:4 t.cs
No warnings