Я ожидал, что это сработает, но, по-видимому, так, как генерирует ИЛ, он бросает NullReferenceException
. Почему компилятор не может генерировать аналогичный код для запросов?
В случае ThisWorks
компилятор генерирует код, который замыкает оставшуюся часть выражения, почему он не может сделать то же самое для случая запроса LINQ?
class Target
{
public ChildTarget Child;
}
class ChildTarget
{
public int[] Values;
}
IEnumerable<int> ThisWorks(Target target) =>
target.Child?.Values.Select(x => x);
IEnumerable<int> ThisDoesNotWork(Target target) =>
from x in target.Child?.Values select x;
ThisWorks(new Target());
ThisDoesNotWork(new Target()); // this throws NullReferenceException
Декомпилированные результаты
private static IEnumerable<int> ThisDoesNotWork(Target target)
{
ChildTarget child = target.Child;
IEnumerable<int> values = (child != null) ? child.Values : null;
Func<int, int> func;
if ((func = Program._func) == null)
{
func = (Program._func = new Func<int, int>(Program._funcMethod));
}
return values.Select(func);
}
private static IEnumerable<int> ThisWorks(Target target)
{
ChildTarget child = target.Child;
IEnumerable<int> values;
if (child == null)
{
values = null;
}
else
{
IEnumerable<int> values = child.Values;
Func<int, int> func;
if ((func = Program._func2) == null)
{
func = (Program._func2= new Func<int, int>(Program._funcMethod2));
}
values = values.Select(func);
}
return values;
}