คำสั่งLINQต่อไปนี้ทำงานอย่างไร
นี่คือรหัสของฉัน:
var list = new List<int>{1,2,4,5,6};
var even = list.Where(m => m%2 == 0);
list.Add(8);
foreach (var i in even)
{
Console.WriteLine(i);
}
เอาท์พุท: 2, 4, 6, 8
ทำไม2, 4, 6
ล่ะ
คำสั่งLINQต่อไปนี้ทำงานอย่างไร
นี่คือรหัสของฉัน:
var list = new List<int>{1,2,4,5,6};
var even = list.Where(m => m%2 == 0);
list.Add(8);
foreach (var i in even)
{
Console.WriteLine(i);
}
เอาท์พุท: 2, 4, 6, 8
ทำไม2, 4, 6
ล่ะ
คำตอบ:
เอาท์พุทเป็น2,4,6,8
เพราะการดำเนินการรอการตัดบัญชี
จริงแล้วแบบสอบถามจะถูกดำเนินการเมื่อมีการทำซ้ำตัวแปรของแบบสอบถามไม่ใช่เมื่อสร้างตัวแปรคิวรี สิ่งนี้เรียกว่าการดำเนินการรอการตัดบัญชี
- Suprotim Agarwal "การดำเนินการสืบค้นข้อมูลที่ล่าช้าออกไปทันทีใน LINQ"
มีการดำเนินการอื่นที่เรียกว่าการดำเนินการค้นหาทันทีซึ่งมีประโยชน์สำหรับการแคชผลลัพธ์แบบสอบถาม จาก Suprotim Agarwal อีกครั้ง:
เมื่อต้องการบังคับให้เรียกใช้งานการสืบค้นทันทีที่ไม่ได้สร้างค่า Singleton คุณสามารถเรียกใช้
ToList(), ToDictionary(), ToArray(), Count(), Average()
หรือMax()
วิธีการในแบบสอบถามหรือตัวแปรแบบสอบถาม สิ่งเหล่านี้เรียกว่าโอเปอเรเตอร์การแปลงซึ่งอนุญาตให้คุณทำสำเนา / สแนปชอตของผลลัพธ์และการเข้าถึงมีหลายครั้งที่คุณต้องการโดยไม่จำเป็นต้องเรียกใช้แบบสอบถามอีกครั้ง
หากคุณต้องการให้เอาต์พุต2,4,6
ใช้.ToList()
:
var list = new List<int>{1,2,4,5,6};
var even = list.Where(m => m%2 == 0).ToList();
list.Add(8);
foreach (var i in even)
{
Console.WriteLine(i);
}
.First()
, .FirstOrDefault()
, .Single()
และ.SingleOrDefault()
ยังก่อให้เกิดการประเมินผลของแบบสอบถาม
สิ่งนี้เกิดขึ้นเนื่องจากการประมวลผลที่เลื่อนออกไปซึ่งหมายความว่าการคำนวณนิพจน์จะไม่ถูกดำเนินการจนกว่าจะจำเป็นในบางที่ ทำให้ประสิทธิภาพดีขึ้นหากข้อมูลมีขนาดใหญ่เกินไป
เหตุผลนี้คือการประมวลผลนิพจน์แลมบ์ดาที่คุณรอตัดบัญชี แบบสอบถามได้รับการดำเนินการเมื่อคุณเริ่มทำซ้ำใน foreach loop
เมื่อคุณใช้ IEnumerable <> ที่ได้รับจาก LINQ จะมีการสร้างคลาส Enumerator เท่านั้นและการวนซ้ำจะเริ่มเมื่อคุณใช้ในการเดิน
คุณได้รับผลลัพธ์นี้เนื่องจากการประมวลผลที่เลื่อนออกไปซึ่งหมายความว่าผลลัพธ์จะไม่ถูกประเมินจนกว่าจะมีการเข้าถึงครั้งแรก
เพื่อให้ชัดเจนยิ่งขึ้นเพียงเพิ่ม 10 ลงในรายการที่ส่วนท้ายของตัวอย่างแล้วพิมพ์อีกครั้งคุณจะไม่ได้รับ 10 ผลลัพธ์
var list = new List<int>{1,2,4,5,6};
var even = list.Where(m => m%2 == 0).Tolist();
list.Add(8);
foreach (var i in even)
{
Console.WriteLine(i);
}
//new*
list.Add(10);
foreach (var i in even)
{
Console.WriteLine(i);
}
10
ผลลัพธ์
8
ในเอาท์พุทอย่างใดอย่างหนึ่ง