Почему компилятор C# требует "использования неназначенной переменной" перед "yield return" и динамическим?

Компилятор жалуется, что resultingThing в приведенном ниже коде используется перед назначением.

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
        // ...
}

Почему это требует этого?

Я пробовал другую версию метода, в котором нет использования доходности (например, просто return IEnumerable<IThing>), но с параметром dynamic, и я попробовал версию метода, в которой не передается dynamic (то есть, что мы делали в предыдущих версиях C#). Эти компиляции.

1 ответ

Решение

Я, кажется, ошибка компилятора (или ограничение, если вы предпочитаете).

Я сократил минимальный случай отказа до:

static private IThing FindThings(dynamic spec)
{
    IThing resultingThing;
    if ((null!=spec) && dictionary.TryGetValue(spec, out resultingThing))
        return resultingThing;
return null;
}

Который дает ту же самую диагностику компилятора, не вовлекая поиск члена по динамике, ни блоки итератора.

Для справки: моно-компилятор не отключается из-за этого:

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)
    {

    }
}

Составление этого:

dmcs -v -warnaserror -warn:4 t.cs

Нет предупреждений

Другие вопросы по тегам