#dynamic #c#-4.0 #yield-keyword #out-parameters
#динамический #c #-4.0 #yield-ключевое слово #out-parameters
Вопрос:
Компилятор жалуется, что resultingThing
в приведенном ниже коде используется перед назначением.
private IEnumerable<IThing> FindThings(dynamic spec)
{
if (spec == null)
yield break;
IThing resultingThing;
if (spec.Something > 0 amp;amp; dictionary.TryGetValue(spec.Something, out resultingThing))
yield return resultingThing;
else
// ...
}
Почему он утверждает это?
Я пробовал другую версию метода, в которой нет использования yield (например, просто return IEnumerable<IThing>
), но с параметром dynamic, и я пробовал версию метода, в которой не передается dynamic (т. Е. то, что мы делали в предыдущих версиях C #). Они компилируются.
Комментарии:
1. Используете ли вы
resultingThing
вelse
случае?2. Нет, не используется
resultingThing
вelse
. Кроме того, инициализация его вnull
избавляет от ошибки компилятора, как и ожидалось.3. Не совсем идеально, но попробуйте инициализировать,
resultingThing
используяdefault
ключевое слово, т. Е.default(IThing)
. Для ссылочных типов это должно бытьnull
; для типов значений это должно быть эквивалентом типа, созданного по умолчанию.4. Я уменьшил случай ошибки, блок итератора не оказывает никакого влияния, хотя использование dynamic имеет значение, см. Мой обновленный ответ.
Ответ №1:
Похоже, что это ошибка компилятора (или ограничение, если хотите).
Я сократил минимальный случай сбоя до:
static private IThing FindThings(dynamic spec)
{
IThing resultingThing;
if ((null!=spec) amp;amp; dictionary.TryGetValue(spec, out resultingThing))
return resultingThing;
return null;
}
Что дает ту же самую диагностику компилятора, без использования поиска элементов в dynamics или блоков итератора.
Для справки, компилятор mono не использует это:
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) amp;amp; dictionary.TryGetValue(spec, out resultingThing))
return resultingThing;
return null;
}
public static void Main(string[] s)
{
}
}
Компиляция этого:
dmcs -v -warnaserror -warn:4 t.cs
Никаких предупреждений
Комментарии:
1. Вы не сказали, была ли ваша версия протестирована с помощью компилятора Microsoft C #. Итак, я попробовал это, и это действительно приводит к ошибке, указанной в названии вопроса.
2. Да, это был компилятор Microsoft. Похоже, что это действительно ошибка.