объем переменных циклов foreach!
var l = new List<Func<string>>();
var strings = new[] { "Lorem" , "ipsum", "dolor", "sit", "amet" };
foreach (var s in strings)
{
l.Add(() => s);
}
foreach (var a in l)
Console.WriteLine(a());
печать пять "amet", в то время как следующий пример хорошо работает
var l = new List<Func<string>>();
var strings = new[] { "Lorem" , "ipsum", "dolor", "sit", "amet" };
foreach (var s in strings)
{
var t = s;
l.Add(() => t);
}
foreach (var a in l)
Console.WriteLine(a());
Будет больше смысла, если вы разделите два вызова:
string[] source = { "1", "A", "B" };
var tmp = Array.ConvertAll(source, c => new Source(c));
var sourceObjects = tmp.ToArray();
Теперь он указывает на последнюю строку как на проблему. Другими словами, вызов Array.ConvertAll
знает, что источник не нулевой, но вызов ToArray ()
не знает, что tmp
выиграл 'не имеет значения null.
(Ваш пример также немного сбивает с толку из-за использования имени source
в вашем исходном коде - ошибка все равно будет использовать источник
, даже если вы' d назвал вашу переменную чем-то совершенно другим, поскольку он относится к первому параметру в Enumerable.ToArray
.)
В основном я считаю, что все это сработает, когда Array.ConvertAll получит соответствующее постусловие ненулевого значения. А до тех пор это поможет:
string[] source = { "1", "A", "B" };
var tmp = Array.ConvertAll(source, c => new Source(c));
Contract.Assume(tmp != null);
var sourceObjects = tmp.ToArray();
Я согласен, что такие вещи раздражают, но я уверен, что они быстро улучшатся, поскольку MS добавляет все больше и больше контрактов в BCL. Важно отметить, что это не проблема с самой статической проверкой.
(Фактически, Array.ConvertAll
также не имеет предварительного условия - если вы установите переменная источника
в null во втором фрагменте кода выше, он все равно не будет жаловаться.)