Почему компилятор С# требует «использования неназначенной переменной» до «доходного возврата» и динамического?

Компилятор жалуется, что 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#). Эти компилируются.


person Kit    schedule 18.05.2011    source источник
comment
Вы используете resultingThing в случае else?   -  person adrianbanks    schedule 19.05.2011
comment
Нет, не используйте resultingThing в else. Кроме того, инициализация его значением null избавляет от ошибки компилятора, как и ожидалось.   -  person Kit    schedule 19.05.2011
comment
Не совсем идеально, но попробуйте инициализировать resultingThing с помощью ключевого слова default, то есть default(IThing). Для ссылочных типов это должно быть null; для типов значений он должен быть эквивалентом типа, созданного по умолчанию.   -  person Nathan Ernst    schedule 19.05.2011
comment
Я уменьшил количество ошибок, блок итератора не влияет, хотя использование динамического имеет значение, см. мой обновленный ответ.   -  person sehe    schedule 19.05.2011


Ответы (1)


I кажется ошибкой компилятора (или ограничением, если хотите).

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

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

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

person sehe    schedule 18.05.2011
comment
Вы не сказали, тестировалась ли ваша версия с помощью компилятора Microsoft C#. Итак, я попробовал, и на самом деле он выдает ошибку, указанную в заголовке вопроса. - person Jeffrey L Whitledge; 19.05.2011
comment
Да, это был компилятор Microsoft. Похоже, это действительно баг. - person Kit; 19.05.2011