IEnumerable <วัตถุ> a = ใหม่ IEnumerable <วัตถุ> (); ฉันสามารถทำสิ่งนี้ได้หรือไม่?


95

ฉันต้องการสร้างอินสแตนซ์ใหม่ของวัตถุ IEnumerable<object>

ฉันสามารถทำสิ่งนี้ได้หรือไม่?

IEnumerable<object> a = new IEnumerable<object>();

ที่เกี่ยวข้อง: stackoverflow.com/questions/191013/…
Josh Lee

1
ไม่และมันไม่สมเหตุสมผลด้วยซ้ำ
CodesInChaos

3
@ WingMan20-10: นั่นเปลี่ยนทุกอย่าง คุณไม่สามารถเพิ่มลงในแบบทั่วไปIEnumerable<T>ได้ List<T>คุณต้องใช้สิ่งที่ต้องการ
สัน

1
ในกรณีนี้คุณต้องมีรายการอาร์เรย์คอนกรีต <object> objs = new IEnumerable <object> คุณไม่สามารถเพิ่มสินค้าลงใน iterator เพราะมันไม่ ... คอลเลกชันของมัน iterator :)
user44298

1
@ivo หมายเหตุ: ที่IEnumerable<T>ไม่ได้เป็นตัวแทนของ iterator - มันแสดงให้เห็นถึงiterableลำดับ IEnumerator<T>ตัวเองแสดงถึงตัววนซ้ำ
Jon Skeet

คำตอบ:


117

เช่นคุณสามารถสร้างตัวอย่างของซึ่งการดำเนินการList<object> IEnumerable<object>ตัวอย่าง:

List<object> list = new List<object>();
list.Add(1);
list.Add(4);
list.Add(5);

IEnumerable<object> en = list;
CallFunction(en);

11
เนื่องจากคำถามแสดงการใช้ยาสามัญเนื่องจากตัวอย่างของประเภทที่ไม่ใช้ทั่วไปIEnumerable<T>เป็นแนวคิดที่ไม่ดี IMO
Jon Skeet

มีปัญหากับการใช้ CallFunction (listAsEnumerable ()) แทน IEnumerable <object> en = list; ...
Gina Marano

ฉันจะใช้อาร์เรย์ที่มีตัวเริ่มต้นตามตัวอักษรถ้าเป็นไปได้มันเป็นประเภทการนับที่มีประสิทธิภาพและน้ำหนักเบาที่สุดที่มีอยู่ใน. NET และไม่มีค่าใช้จ่ายของ List <> ควรใช้รายการเฉพาะเมื่อคุณต้องการหรือต้องการที่จะกลายพันธุ์หลังจากการเริ่มต้นเท่านั้น นอกจากนี้ควรเพิ่ม System.Linq และเรียกใช้. AsEnumerable () ในอาร์เรย์หรือรายการ
มาร์ค

33

เนื่องจากคุณระบุแล้วว่าต้องการเพิ่มสิ่งที่คุณต้องการไม่ใช่เรื่องง่ายIEnumerable<T>แต่อย่างน้อยก็คือICollection<T>. ฉันขอแนะนำให้ใช้สิ่งList<T>นี้:

List<object> myList=new List<object>();
myList.Add(1);
myList.Add(2);
myList.Add(3);

คุณสามารถใช้ myList ทุกIEnumerable<object>คาดว่าเนื่องจากการดำเนินการList<object>IEnumerable<object>

(คำตอบเก่าก่อนการชี้แจง)

คุณไม่สามารถสร้างอินสแตนซ์ได้IEnumerable<T>เนื่องจากเป็นอินเทอร์เฟซปกติ (บางครั้งอาจระบุการใช้งานเริ่มต้นได้ แต่โดยปกติจะใช้กับ COM เท่านั้น)

ดังนั้นสิ่งที่คุณต้องการจริงๆคือยกตัวอย่างคลาสที่ใช้อินเตอร์เฟซ IEnumerable<T>พฤติกรรมแตกต่างกันไปขึ้นอยู่กับคลาสที่คุณเลือก

สำหรับลำดับว่างให้ใช้:

IEnumerable<object> e0=Enumerable.Empty<object>();

IEnumerable<T>สำหรับนับว่างเปล่าไม่ใช่คุณสามารถใช้คอลเลกชันบางอย่างที่นำไปปฏิบัติ ทางเลือกส่วนใหญ่จะเป็นอาร์เรย์T[], หรือถ้าคุณต้องการเปลี่ยนไม่ได้List<T>ReadOnlyCollection<T>

IEnumerable<object> e1=new object[]{1,2,3};
IEnumerable<object> e2=new List<object>(){1,2,3};
IEnumerable<object> e3=new ReadOnlyCollection(new object[]{1,2,3});

อีกวิธีหนึ่งในการใช้งานIEnumerable<T>คือคุณลักษณะตัววนซ้ำที่นำมาใช้ใน C # 3

IEnumerable<object> MyIterator()
{
  yield return 1;
  yield return 2;
  yield return 3;
}

IEnumerable<object> e4=MyIterator();

33

Emptyทางออกก็จะใช้

IEnumerable<object> a = Enumerable.Empty<object>();

มีเธรดเกี่ยวกับ SO เกี่ยวกับเรื่องนี้: จะดีกว่าไหมถ้าใช้ Enumerable.Empty () เมื่อเทียบกับรายการใหม่เพื่อเริ่มต้น IEnumerable?


2
คำตอบที่สะอาดที่สุด!
eddyP23

24

ไม่คุณทำไม่ได้เนื่องจากIEnumerableเป็นอินเทอร์เฟซ

คุณควรจะสามารถสร้างอินสแตนซ์ว่างของประเภทที่ไม่ใช่อินเทอร์เฟซส่วนใหญ่ที่ใช้งานIEnumerableได้เช่น: -

IEnumerable<object> a = new object[] { };

หรือ

IEnumerable<object> a = new List<object>();

@AdamRalph: ฉันลงคะแนนแล้วก็ฟุ้งซ่านจึงไม่สามารถแสดงความคิดเห็นได้ทันที อินเทอร์เฟซเป็นประเภทดังนั้นคำตอบของคุณจึงผิดอย่างมากเนื่องจากเป็นการเผยแพร่ความเข้าใจผิดทั่วไป
สัน

7

ไม่คุณไม่สามารถทำได้ ใช้โค้ดบรรทัดต่อไปนี้แทน:

IEnumerable<int> usersIds = new List<int>() {1, 2, 3}.AsEnumerable();

ฉันหวังว่ามันจะช่วยได้


1

ฉันต้องการสร้างวัตถุหรือรายการที่แจกแจงได้ใหม่และสามารถเพิ่มเข้าไปได้

ความคิดเห็นนี้เปลี่ยนแปลงทุกอย่าง คุณไม่สามารถเพิ่มลงในแบบทั่วไปIEnumerable<T>ได้ หากคุณต้องการอยู่กับอินเทอร์เฟซSystem.Collections.Genericคุณต้องใช้คลาสที่ใช้ICollection<T>เช่นList<T>.


1

เหตุผลหลักคือการที่เราไม่สามารถสร้างวัตถุของอินเตอร์เฟซและ IEnumerable เป็นอินเตอร์เฟซ เราจำเป็นต้องสร้างวัตถุของคลาสที่ใช้อินเทอร์เฟซ นี่คือเหตุผลหลักที่เราไม่สามารถสร้าง object ของ IEnumerable ได้โดยตรง


0

ไม่มี IEnumerable เป็นอินเทอร์เฟซคุณไม่สามารถสร้างอินเทอร์เฟซได้

คุณสามารถทำสิ่งนี้ได้

IEnumerable<object> a = new object[0];

เป็นไปได้ไหมที่จะสร้างอินสแตนซ์ของ COM interface แบบนั้น @Jon Skeet?
Arsen Mkrtchyan

อย่างแน่นอน แปลก แต่จริง ดูstackoverflow.com/questions/1093536/…และmsmvps.com/blogs/jon_skeet/archive/2009/07/07/…
Jon Skeet

1
ฉันคิดว่าเป็นไปได้ที่จะระบุการใช้งานเริ่มต้นที่สร้างอินสแตนซ์แทนอินเทอร์เฟซสำหรับอินเตอร์เฟส COM
CodesInChaos

@JonSkeet ไม่ถูกต้องกว่าที่จะบอกว่าการเรียกnew SomeComInterface()อินสแตนซ์ "CoClass" ที่เกี่ยวข้องกับอินเทอร์เฟซแทนที่จะเป็นอินสแตนซ์อินเทอร์เฟซเอง
กลัว

@phoog: ถูกต้อง แต่สิ่งที่สำคัญและแปลกคือคุณสามารถใช้newกับอินเทอร์เฟซในบางสถานการณ์ได้
Jon Skeet

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