5

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.

adrianbanks
  • 81,306
  • 22
  • 176
  • 206
Kit
  • 20,354
  • 4
  • 60
  • 103
  • Are you using `resultingThing` in the `else` case? – adrianbanks May 18 '11 at 22:27
  • No not using `resultingThing` in the `else`. Also, initializing it to `null` gets rid of the compiler error as expected. – Kit May 18 '11 at 22:40
  • Not really ideal, but try initializing `resultingThing` using the `default` keyword, i.e. `default(IThing)`. For reference types, this should be `null`; for value types, it should be the equivalent of a default-constructed type. – Nathan Ernst May 18 '11 at 22:58
  • I have reduced the error case, the iterator block has no influence, though the use of dynamic is relevant, see my updated answer. – sehe May 18 '11 at 23:03

1 Answers1

1

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

sehe
  • 374,641
  • 47
  • 450
  • 633
  • You didn't say whether your version was tested with the Microsoft C# compiler. So I tried it, and it does, in fact, produce the error given in the question title. – Jeffrey L Whitledge May 18 '11 at 22:45
  • Yes, it was the Microsoft compiler. It looks like it is indeed a bug. – Kit May 19 '11 at 19:19