ICollection<T>
ฉันเห็นมากในบทเรียนที่มีคุณสมบัติเป็นลูกศร
นี่เป็นข้อกำหนดที่จำเป็นสำหรับ Entity Framework หรือไม่ ฉันสามารถใช้IEnumerable
?
อะไรคือวัตถุประสงค์หลักในการใช้งานICollection
แทนIEnumerable
หรือแม้กระทั่งList<T>
?
ICollection<T>
ฉันเห็นมากในบทเรียนที่มีคุณสมบัติเป็นลูกศร
นี่เป็นข้อกำหนดที่จำเป็นสำหรับ Entity Framework หรือไม่ ฉันสามารถใช้IEnumerable
?
อะไรคือวัตถุประสงค์หลักในการใช้งานICollection
แทนIEnumerable
หรือแม้กระทั่งList<T>
?
คำตอบ:
โดยปกติสิ่งที่คุณเลือกจะขึ้นอยู่กับวิธีการที่คุณต้องการเข้าถึง โดยทั่วไป - IEnumerable<>
(MSDN: http://msdn.microsoft.com/en-us/library/system.collections.ienumerable.aspx ) สำหรับรายการของวัตถุที่ต้องทำซ้ำผ่านเท่านั้นICollection<>
(MSDN: http: // msdn.microsoft.com/en-us/library/92t2ye13.aspx ) สำหรับรายการของวัตถุที่จำเป็นต้องทำซ้ำและแก้ไขList<>
เพื่อดูรายการของวัตถุที่ต้องทำซ้ำผ่านแก้ไขจัดเรียง ฯลฯ (ดูที่นี่ สำหรับรายการทั้งหมด: http://msdn.microsoft.com/en-us/library/6sh2ey19.aspx )
จากมุมมองที่เฉพาะเจาะจงมากขึ้นการโหลดแบบขี้เกียจจะเข้ามาเล่นโดยเลือกประเภท ตามค่าเริ่มต้นคุณสมบัติการนำทางใน Entity Framework มาพร้อมกับการติดตามการเปลี่ยนแปลงและเป็นพร็อกซี เพื่อให้ผู้รับมอบฉันทะแบบไดนามิกเพื่อสร้างเป็นสถานที่ให้บริการนำทางชนิดเสมือนจริงจะต้องICollection
ดำเนินการ
คุณสมบัติการนำทางที่แสดงถึงจุดสิ้นสุด "จำนวนมาก" ของความสัมพันธ์ต้องส่งคืนชนิดที่ใช้ ICollection โดยที่ T คือประเภทของวัตถุที่ปลายอีกด้านของความสัมพันธ์ - ข้อกำหนดสำหรับการสร้าง POCO Proxies MSDN
ข้อมูลเพิ่มเติมเกี่ยวกับการกำหนดและการจัดการความสัมพันธ์MSDN
List
บ่อย แม้ว่าจะมีค่าใช้จ่ายมากที่สุด แต่ก็มีฟังก์ชั่นการใช้งานมากที่สุด
private IEnumerable<int> _integers = new List<int> { 1, 2, 3 };
ใช้หน่วยความจำเดียวกันกับprivate List<int> _integers = new List<int> { 1, 2, 3 };
List<T>
มีGetEnumerator()
วิธีการแยกออกจากการดำเนินงานของซึ่งผลตอบแทนประเภทโครงสร้างที่ไม่แน่นอนIEnumerable<T>
List<T>.Enumerator
ในบริบทส่วนใหญ่ประเภทนั้นจะให้ประสิทธิภาพที่ดีขึ้นเล็กน้อยกว่าวัตถุฮีปแบบสแตนด์อโลน คอมไพเลอร์ซึ่งตัวแจงนับชนิดเป็ด (ทั้ง C # และ vb.net ทำ) สามารถใช้ประโยชน์จากสิ่งนี้เมื่อสร้างforeach
รหัส ถ้าList<T>
จะโยนไปIEnumrable<T>
ก่อนforeach
ที่IEnumerable<T>.GetEnumerator()
วิธีการที่จะกลับมาเป็นวัตถุกองจัดสรร, การแสดงผลเพิ่มประสิทธิภาพเป็นไปไม่ได้
ICollection<T>
ถูกใช้เนื่องจากIEnumerable<T>
อินเตอร์เฟสไม่มีวิธีในการเพิ่มไอเท็มการลบไอเท็มหรือการแก้ไขการรวบรวม
List<T>
ICollection<T>
การดำเนินการ
ICollection
ไม่อนุญาตให้มีวิธีการเพิ่มรายการใด ๆ แต่ก็ยังเป็นประโยชน์เสริมIEnumerable<T>
เพราะมันให้Count
สมาชิกซึ่งโดยทั่วไปจะเร็วกว่าการแจกแจงทุกอย่าง หมายเหตุว่าถ้าIList<Cat>
หรือICollection<Cat>
ถูกส่งไปยังรหัสคาดหวังว่าIEnumerable<Animal>
การCount()
วิธีขยายจะเร็วถ้ามันดำเนินการที่ไม่ได้ทั่วไปICollection
แต่ไม่ถ้ามันใช้อินเตอร์เฟซทั่วไปตั้งแต่ทั่วไปจะไม่ดำเนินการICollection<Cat>
ICollection<Animal>
ตอบคำถามของคุณเกี่ยวกับList<T>
:
List<T>
เป็นคลาส; การระบุอินเทอร์เฟซทำให้มีความยืดหยุ่นในการใช้ คำถามที่ดีกว่าคือ "ทำไมไม่IList<T>
"
ในการตอบคำถามนั้นให้พิจารณาสิ่งที่IList<T>
เพิ่มไปที่ICollection<T>
: การจัดทำดัชนีจำนวนเต็มซึ่งหมายความว่ารายการนั้นมีคำสั่งโดยพลการบางอย่างและสามารถดึงข้อมูลได้โดยอ้างอิงไปยังลำดับนั้น นี่อาจไม่ได้มีความหมายในกรณีส่วนใหญ่เนื่องจากรายการอาจต้องสั่งแตกต่างกันในบริบทที่แตกต่างกัน
มีความแตกต่างพื้นฐานระหว่าง ICollection และ IEnumerable
โปรแกรมง่าย ๆ :
using System;
using System.Collections;
using System.Collections.Generic;
namespace StackDemo
{
class Program
{
static void Main(string[] args)
{
List<Person> persons = new List<Person>();
persons.Add(new Person("John",30));
persons.Add(new Person("Jack", 27));
ICollection<Person> personCollection = persons;
IEnumerable<Person> personEnumeration = persons;
// IEnumeration
// IEnumration Contains only GetEnumerator method to get Enumerator and make a looping
foreach (Person p in personEnumeration)
{
Console.WriteLine("Name:{0}, Age:{1}", p.Name, p.Age);
}
// ICollection
// ICollection Add/Remove/Contains/Count/CopyTo
// ICollection is inherited from IEnumerable
personCollection.Add(new Person("Tim", 10));
foreach (Person p in personCollection)
{
Console.WriteLine("Name:{0}, Age:{1}", p.Name, p.Age);
}
Console.ReadLine();
}
}
class Person
{
public string Name { get; set; }
public int Age { get; set; }
public Person(string name, int age)
{
this.Name = name;
this.Age = age;
}
}
}
ฉันจำได้ด้วยวิธีนี้:
IEnumerable มีหนึ่งเมธอด GetEnumerator () ที่อนุญาตให้หนึ่งอ่านค่าในคอลเลกชัน แต่ไม่ได้เขียนลงไป ความซับซ้อนของการใช้ตัวแจงนับส่วนใหญ่ได้รับการดูแลโดยเราสำหรับแต่ละคำสั่งใน C # IEnumerable มีหนึ่งคุณสมบัติ: ปัจจุบันซึ่งส่งคืนองค์ประกอบปัจจุบัน
ICollection ใช้ IEnumerable และเพิ่มคุณสมบัติเพิ่มเติมไม่กี่รายการที่การใช้งานมากที่สุดคือ Count ICollection เวอร์ชันทั่วไปใช้เมธอด Add () และ Remove ()
IList ใช้ทั้ง IEnumerable และ ICollection และเพิ่มการเข้าถึงการจัดทำดัชนีจำนวนเต็มในรายการ (ซึ่งโดยทั่วไปไม่จำเป็นต้องใช้เนื่องจากการสั่งซื้อจะทำในฐานข้อมูล)
แนวคิดพื้นฐานของการใช้ICollection
คือการให้อินเทอร์เฟซสำหรับการเข้าถึงข้อมูลจำนวน จำกัด แบบอ่านอย่างเดียว ในความเป็นจริงคุณมีคุณสมบัติICollection.Count IEnumerable
เหมาะสำหรับสายข้อมูลที่คุณอ่านจนถึงจุดตรรกะบางเงื่อนไขที่ระบุโดยผู้บริโภคหรือจนถึงจุดสิ้นสุดของการแจงนับ
ICollection
อ่านอย่างเดียวในขณะที่ICollection<T>
ไม่อยู่
โดยทั่วไปแล้วคุณสมบัติการนำทางจะถูกกำหนดเป็นเสมือนเพื่อให้สามารถใช้ประโยชน์จากฟังก์ชันการทำงานของ Entity Framework บางอย่างเช่นการโหลดแบบสันหลังยาว
หากคุณสมบัติการนำทางสามารถเก็บเอนทิตีหลายรายการ (ในความสัมพันธ์แบบกลุ่มต่อกลุ่มหรือหลายกลุ่ม) จะต้องเป็นรายการที่สามารถเพิ่มลบและอัปเดตรายการเช่น ICollection ได้
สิ่งที่ฉันได้ทำในมีที่ผ่านมาประกาศคอลเลกชันระดับชั้นของฉันโดยใช้IList<Class>
, ICollection<Class>
หรือIEnumerable<Class>
(ถ้ารายการคงที่) ขึ้นอยู่กับว่าหรือไม่ฉันจะต้องทำจำนวนต่อไปนี้ในวิธีการในพื้นที่เก็บข้อมูลของฉันใด ๆการระบุการจัดเรียง / สั่งซื้อหรือปรับเปลี่ยน . เมื่อฉันต้องการแจกแจง (และอาจจะเรียงลำดับ) บนวัตถุจากนั้นฉันสร้าง temp List<Class>
เพื่อทำงานกับคอลเลกชันภายในวิธี IEnumerable ฉันคิดว่าการฝึกฝนนี้จะมีผลก็ต่อเมื่อการรวบรวมมีขนาดค่อนข้างเล็ก แต่อาจเป็นแนวปฏิบัติที่ดีโดยทั่วไป idk โปรดแก้ไขให้ฉันด้วยหากมีหลักฐานว่าทำไมสิ่งนี้ถึงไม่เป็นการปฏิบัติที่ดี
ให้ลองคิดนอกกรอบด้วย / โดยลอจิกและทำความเข้าใจกับอินเทอร์เฟซทั้งสามในคำถามของคุณ:
เมื่อคลาสของอินสแตนซ์บางตัวใช้อินเทอร์เฟซ System.Collection.IEnumerable ดังนั้นในคำง่าย ๆ เราสามารถพูดได้ว่าอินสแตนซ์นี้มีทั้งแบบนับจำนวนและ iterable ซึ่งหมายความว่าอินสแตนซ์นี้อนุญาตให้วนซ้ำไป สำรวจ / วนซ้ำไอเท็มและองค์ประกอบทั้งหมดที่อินสแตนซ์นี้มี
ซึ่งหมายความว่านี่เป็นไปได้ที่จะระบุรายการและองค์ประกอบทั้งหมดที่อินสแตนซ์นี้มี
ทุกคลาสที่ใช้อินเทอร์เฟซ System.Collection.IEnumerable ยังใช้เมธอด GetEnumerator ที่ไม่มีอาร์กิวเมนต์และส่งคืนอินสแตนซ์ System.Collections.IEnumerator
อินสแตนซ์ของ System.Collections.IEnumerator อินเทอร์เฟซทำงานคล้ายกับตัววนซ้ำ c ++
เมื่อคลาสของอินสแตนซ์บางตัวใช้ส่วนต่อประสาน System.Collection.ICollection ในคำง่ายๆเราสามารถพูดได้ว่าอินสแตนซ์นี้คือชุดของสิ่งต่าง ๆ
รุ่นทั่วไปของอินเทอร์เฟซนี้เช่น System.Collection.Generic.ICollection เป็นข้อมูลที่มากกว่าเนื่องจากอินเทอร์เฟซทั่วไปนี้ระบุสิ่งที่ประเภทของสิ่งต่าง ๆ ในคอลเลกชันอย่างชัดเจน
นี่คือเหตุผลที่สมเหตุสมผลเหตุผลตรรกะและทำให้รู้สึกว่า System.Collections.ICollection อินเตอร์เฟสสืบทอดมาจาก System.Collections.IE อินเทอร์เฟซที่นับไม่ได้เพราะในทางทฤษฎีแล้วทุกคอลเลกชันก็มีทั้งที่นับได้และสามารถทำซ้ำได้และในทางทฤษฎี ในทุกคอลเลกชัน
ส่วนต่อประสาน System.Collections.ICollection หมายถึงคอลเลกชันแบบไดนามิก จำกัด ที่มีการเปลี่ยนแปลงซึ่งหมายความว่ารายการที่มีอยู่สามารถลบออกจากคอลเลกชันและรายการใหม่สามารถเพิ่มลงในคอลเลกชันเดียวกัน
สิ่งนี้อธิบายว่าทำไมส่วนต่อประสาน System.Collections.ICollection มีวิธีการ "เพิ่ม" และ "ลบ"
เนื่องจากอินสแตนซ์ของ System.Collections.Collection ส่วนต่อประสานนั้นเป็นคอลเลกชันที่ จำกัด ดังนั้นคำว่า "finite" จึงมีความหมายว่าคอลเลกชันของส่วนต่อประสานนี้ทุกครั้งจะมีจำนวนรายการและองค์ประกอบที่แน่นอนอยู่เสมอ
คุณสมบัติ Count of System.Collections.ICollection interface จะส่งคืนหมายเลขนี้
ส่วนต่อประสาน System.Collections.IEnumerable ไม่มีวิธีการและคุณสมบัติเหล่านี้ที่ส่วนต่อประสาน System.Collections.ICollection เนื่องจากมันไม่ได้ทำให้รู้สึกว่า System.Collections.IEnumerable จะมีวิธีการและคุณสมบัติเหล่านี้ที่ System.Collections.ICollection มี
ลอจิกยังบอกอีกว่าทุกตัวอย่างที่มีทั้งจำนวนและ iterable นั้นไม่จำเป็นต้องเป็นของสะสมและไม่จำเป็นต้องเปลี่ยนแปลง
เมื่อฉันพูดว่าเปลี่ยนแปลงได้ฉันหมายความว่าอย่าคิดทันทีว่าคุณสามารถเพิ่มหรือลบบางสิ่งออกจากสิ่งที่นับได้และสามารถทำซ้ำได้
ถ้าฉันเพิ่งสร้างลำดับที่แน่นอนของจำนวนเฉพาะเช่นลำดับที่ จำกัด ของจำนวนเฉพาะนี้เป็นตัวอย่างของ System.Collections.IE อินเทอร์เฟซที่นับไม่ได้เพราะตอนนี้ฉันสามารถไปหาจำนวนเฉพาะทั้งหมดในลำดับที่ จำกัด นี้ในลูปเดียว และทำสิ่งที่ฉันต้องการจะทำกับพวกเขาแต่ละคนเช่นการพิมพ์แต่ละรายการไปที่หน้าต่างคอนโซลหรือหน้าจอ แต่ลำดับที่ จำกัด ของจำนวนเฉพาะนี้ไม่ได้เป็นตัวอย่างของ System.Collections.Collections.Collections interface เพราะสิ่งนี้ไม่สมเหตุสมผล เพิ่มหมายเลขคอมโพสิตลงในลำดับที่ จำกัด ของจำนวนเฉพาะ
นอกจากนี้คุณต้องการในการทำซ้ำครั้งถัดไปเพื่อให้ได้จำนวนเฉพาะจำนวนที่ใกล้เคียงที่สุดไปยังหมายเลขเฉพาะปัจจุบันในการทำซ้ำปัจจุบันดังนั้นถ้าคุณไม่ต้องการลบหมายเลขเฉพาะที่มีอยู่ออกจากลำดับที่แน่นอนของตัวเลขเฉพาะ
นอกจากนี้คุณอาจต้องการใช้โค้ดและเขียน "return return" ในเมธอด GetEnumerator ของอินเตอร์เฟส System.Collections.IEnumerable เพื่อสร้างหมายเลขเฉพาะและไม่จัดสรรอะไรบนฮีปหน่วยความจำแล้วมอบหมาย Garbage Collector (GC) ให้กับทั้งสอง deallocate และทำให้หน่วยความจำว่างจากฮีปนี้เพราะเห็นได้ชัดว่าเป็นการเสียหน่วยความจำระบบปฏิบัติการและลดประสิทธิภาพลง
การจัดสรรหน่วยความจำแบบไดนามิกและการจัดสรรคืนบนฮีปควรทำเมื่อเรียกใช้เมธอดและคุณสมบัติของ System.Collections.ICollection interface แต่ไม่ใช่เมื่อทำการเรียกใช้เมธอดและคุณสมบัติของ System.Collections.IEnumerable interface (แม้ว่า System.Collections.IEnumerable interface เท่านั้น) 1 เมธอดและคุณสมบัติ 0)
ตามสิ่งที่คนอื่นพูดในเว็บเพจสแต็คโอเวอร์โฟลว์อินเทอร์เฟซ System.Collections.IList จะแสดงถึงลำดับที่สามารถสั่งซื้อได้คอลเลกชันนี้และอธิบายว่าทำไมวิธีการของการทำงานของอินเตอร์เฟซ System.Collections.IList กับดัชนีในทางตรงกันข้ามกับเหล่านี้ของอินเตอร์เฟซ System.Collections.ICollection
ในระยะสั้น System.Collections.ICollection อินเตอร์เฟสไม่ได้หมายความว่าอินสแตนซ์ของมันสามารถสั่งซื้อได้ แต่อินเตอร์เฟส System.Collections.IList นั้นหมายความว่า
ชุดที่ถูกสั่งในเชิงทฤษฎีเป็นกรณีพิเศษของชุดที่ไม่มีการเรียงลำดับ
นอกจากนี้ยังสมเหตุสมผลและอธิบายว่าทำไมส่วนต่อประสาน System.Collections.IList จึงรับส่วนต่อประสาน System.Collections.ICollection
List
ควรจะดีกว่านี้อีกใช่ไหม