LINQ ที่ไหน () เทียบกับ FindAll ()


126

ใครช่วยอธิบายได้ว่าฟังก์ชัน LINQ ที่ (.. ) และ FindAll (.. ) แตกต่างกันอย่างไร ดูเหมือนทั้งคู่จะทำสิ่งเดียวกัน ...


เป็นไปได้ที่จะซ้ำกันของFindAll vs Where extension-method
Ryan Gates

คำตอบ:


204

FindAll()เป็นฟังก์ชันในList<T>ประเภทไม่ใช่วิธีการขยาย LINQ เช่นWhere. วิธีการขยาย LINQ ใช้งานได้กับทุกประเภทที่ใช้IEnumerableในขณะที่FindAllสามารถใช้ได้เฉพาะกับList<T>อินสแตนซ์ (หรืออินสแตนซ์ของคลาสที่สืบทอดมาจากมัน)

นอกจากนี้ยังแตกต่างกันในวัตถุประสงค์ที่แท้จริง Whereส่งคืนอินสแตนซ์ของIEnumerableสิ่งที่ดำเนินการตามความต้องการเมื่อวัตถุถูกแจกแจง FindAllส่งคืนใหม่List<T>ที่มีองค์ประกอบที่ร้องขอ FindAllเป็นเหมือนการโทรในตัวอย่างของWhere(...).ToList()IEnumerable


20
ใช่ findall รุ่นขี้เกียจอยู่ที่ไหน
Pierreten

2
code.msdn.microsoft.com/LINQ-Query-Execution-ce0d3b95อธิบายความแตกต่างระหว่าง lazy (รอการตัดบัญชี) และการดำเนินการทันที โดยทั่วไปในบางกรณีคุณไม่จำเป็นต้องมีรายการทั้งหมดคุณอาจต้องการวนซ้ำรายการจนกว่าจะมีอะไรเกิดขึ้นจากนั้นจึงหยุด นี่คือจุดที่ความขี้เกียจมีประโยชน์ แต่ขึ้นอยู่กับการนำไปใช้งานอาจนำไปสู่ผลลัพธ์ที่คาดเดาไม่ได้ (ทั้งหมดอธิบายไว้ในลิงค์) หวังว่านี่จะช่วยได้
nurchi

10

ความแตกต่างที่ยิ่งใหญ่ที่สุดสำหรับฉันคือ FindAll มีอยู่ใน. Net 2.0 ด้วย ฉันไม่มีความหรูหราในการเขียนโปรแกรมใน. Net 3.5 เสมอไปดังนั้นฉันจึงพยายามจำวิธีการ 'เนทีฟ' ของคอลเลกชันทั่วไป

เกิดขึ้นหลายครั้งที่ฉันใช้วิธีรายการที่มีอยู่แล้วด้วยตัวเองเพราะฉันไม่สามารถ LINQ ได้

สิ่งที่ฉันพบว่ามีประโยชน์ในกรณีนี้คือเมื่อใช้ VS2008 ฉันสามารถใช้การอนุมานประเภทและไวยากรณ์แลมบ์ดาได้ คุณลักษณะเหล่านี้เป็นคุณลักษณะของคอมไพเลอร์ไม่ใช่คุณลักษณะของกรอบ ซึ่งหมายความว่าฉันสามารถเขียนสิ่งนี้ได้และยังคงอยู่ภายใน. Net 2.0:

var myOddNums = myNums.FindAll(n => n%2==1);

แต่ถ้าคุณมี LINQ การรักษาความแตกต่างระหว่างการดำเนินการรอการตัดบัญชีและการดำเนินการทันทีเป็นสิ่งสำคัญ


6

ถ้าฉันจำได้อย่างถูกต้องความแตกต่างที่สำคัญ (นอกเหนือจากสิ่งที่นำไปใช้กับ: IEnumerable<T>เทียบกับList<T>) คือWhereการดำเนินการรอการตัดบัญชีโดยที่มันไม่ได้ทำการค้นหาจนกว่าคุณจะต้องการ - โดยใช้มันใน foreach loop เป็นต้น FindAllเป็นวิธีการดำเนินการทันที


3

ฉันไม่ได้ทดสอบบางอย่างอยู่ในรายชื่อของวัตถุ 80K และพบว่าFind()สามารถเป็นได้ถึง 1000% เร็วกว่าการใช้ด้วยWhere FirstOrDefault()ฉันไม่รู้จนกระทั่งทดสอบตัวจับเวลาก่อนและหลังการโทรแต่ละครั้ง บางครั้งมันเป็นเวลาเดียวกันเวลาอื่น ๆ มันเร็วกว่า


5
คุณลองเข้าถึงคอลเล็กชันด้วยหรือไม่ นับได้โดยที่ () ใช้การดำเนินการที่รอการตัดบัญชีและไม่ได้รับการประเมินก่อนที่จะเข้าถึงคอลเล็กชันซึ่งอาจนำไปสู่ความคิดที่ผิดว่ามันเร็วขึ้นจริงหรือไม่ อย่างไรก็ตามส่วนใหญ่แล้วโดยทั่วไปจะใช้การแจงนับได้เร็วกว่าการรวบรวมแบบคงที่ (เช่น Type <T> และ Array <T>)
Sebastian Job Bjørnager Jensen

คำถามเกี่ยวกับ FindAll เห็นได้ชัดว่า Find จะเร็วกว่า Where (รับค่าทั้งหมด) และรับ FirstOrDefault
Vivek MVK
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.