Bu, LINQ kullanarak ayaklarını ıslatan insanlar için bilinen bir tuzaktır:
public class Program
{
public static void Main()
{
IEnumerable<Record> originalCollection = GenerateRecords(new[] {"Jesse"});
var newCollection = new List<Record>(originalCollection);
Console.WriteLine(ContainTheSameSingleObject(originalCollection, newCollection));
}
private static IEnumerable<Record> GenerateRecords(string[] listOfNames)
{
return listOfNames.Select(x => new Record(Guid.NewGuid(), x));
}
private static bool ContainTheSameSingleObject(IEnumerable<Record>
originalCollection, List<Record> newCollection)
{
return originalCollection.Count() == 1 && newCollection.Count() == 1 &&
originalCollection.Single().Id == newCollection.Single().Id;
}
private class Record
{
public Guid Id { get; }
public string SomeValue { get; }
public Record(Guid id, string someValue)
{
Id = id;
SomeValue = someValue;
}
}
}
Özgün koleksiyonu oluşturmak için sağlanan her ad için, select işlevi yeniden değerlendirilmeye devam ettiğinden ve sonuçta ortaya çıkan Record
nesne yeniden oluşturulduğundan , bu "False" yazdıracaktır . Bunu düzeltmek ToList
için sonuna basit bir çağrı eklenebilir GenerateRecords
.
Microsoft bu şekilde uygulayarak ne gibi avantajlar elde etmeyi umuyordu?
Uygulama neden sonuçları dahili bir dizi olarak önbelleğe almasın? Olanların belirli bir kısmı ertelenmiş yürütme olabilir, ancak yine de bu davranış olmadan uygulanabilir.
LINQ tarafından döndürülen bir koleksiyonun belirli bir üyesi değerlendirildikten sonra, dahili bir referans / kopya tutmamak, bunun yerine varsayılan bir davranış olarak aynı sonucu yeniden hesaplayarak ne gibi bir avantaj sağlanır?
Tekrar tekrar hesaplanan bir koleksiyonun aynı üyesi için mantıkta özel bir ihtiyaç olduğu durumlarda, bu isteğe bağlı bir parametre ile belirtilebilir ve varsayılan davranışın aksini yapabilir. Buna ek olarak, ertelenmiş uygulama ile elde edilen hız avantajı, aynı sonuçları sürekli olarak yeniden hesaplamak için geçen zamana göre azaltılır. Son olarak, bu LINQ için yeni olanlar için kafa karıştırıcı bir blok ve sonuçta herkesin programında ince hatalara yol açabilir.
Bunun ne avantajı var ve Microsoft bu görünüşte çok kasıtlı bir karar verdi?
return listOfNames.Select(x => new Record(Guid.NewGuid(), x)).ToList();
Bu size "önbelleğe alınmış kopyanızı" verir. Sorun çözüldü.