2010-09-15 16 views
27

Bu neden bir derleyici hatası oluşturur kapsamaz:Neden bir koleksiyon başlatıcısı ifadesi IEnumerable uygulanmasını gerektirir?

class X { public void Add(string str) { Console.WriteLine(str); } } 

static class Program 
{ 
    static void Main() 
    { 
     // error CS1922: Cannot initialize type 'X' with a collection initializer 
     // because it does not implement 'System.Collections.IEnumerable' 
     var x = new X { "string" }; 
    } 
} 

ama bu değil:

class X : IEnumerable 
{ 
    public void Add(string str) { Console.WriteLine(str); } 
    IEnumerator IEnumerable.GetEnumerator() 
    { 
     // Try to blow up horribly! 
     throw new NotImplementedException(); 
    } 
} 

static class Program 
{ 
    static void Main() 
    { 
     // prints “string” and doesn’t throw 
     var x = new X { "string" }; 
    } 
} 

toplama başlatıcıları kısıtlayan sebebi nedir - Bir Add yöntemi çağrısı için sözdizimsel şeker - olmayan bir arabirimi uygulayan sınıflar için ve Add yöntemine sahip olan ve kullanılmayan?

+4

geri, IEnumerable gerektiren nedeni sadece alamadım C# bazı şeyler vardır. Bu onlardan biri. Başka bir 'foreach'. – leppie

+2

@leppie: Foreach hakkında ne anlamıyorsun? –

+1

@Jon Skeet: Bence leppie, derleyicinin, güçlü bir şekilde yazılan bir dilde bir tür ördek yazma davranışı olan belirli bir arabirime gerek duymadan basitçe bir yöntemin varlığını gerektirdiği gerçeğini ifade eder. –

cevap

23

bir nesne başlatıcı değildir; koleksiyonu başlatıcısı yok. Öyle ki, sadece Add yöntemine sahip olan rasgele olanlardan ziyade koleksiyonları gerçekten temsil eden sınıflara uygulanır. ama GetEnumerator() bir NotImplementedException atılmış - Ben sadece toplama başlatıcıları izin vermek için açıkça IEnumerable "hayata" ettik sık sık itiraf etmeliyim. Erken C# 3'ün gelişiminde, toplama ilklendiriciler ICollection<T> uygulamak zorunda kaldı, ama bu çok kısıtlayıcı olduğu bulunmuştur

Not. Mads Torgersen blogged about this change ve 2006

+0

aynı argüman LINQ sorgusu sözdizimi için geçerli olmaz mı? Yine de herhangi bir arayüz gerektirmez ve hatta “yineleyici değişkeni” tür adı ve “Neresi/Seçimi” nin statik bir yöntem olmasını sağlar… – Timwi

+0

@Timwi: Bir sorgulama olasılığının düşük olmasına rağmen İfade aslında bir koleksiyon başlatıcıdan daha rasgele bir türe karşı derleme yapar - Ben 'Add'in' uygun 'türler' yerine '' Seç 've' Seç 'yöntemlerinden daha fazla' diğer anlamları 'olduğundan şüphelenirim. Ayrıca * uygulanmış olabilirdi tek uygun arabirim LINQ sorguları aklı kontrol * orada olmadığına dikkat - LINQ nesnelere ile herhangi bir ortak arabirimi yok Reaktif Extnesions, düşünmek ... –

+6

Bir gün geçtikçe .NET 2'yi istemeden ilk sürüm ... .NET'teki tüm bu kabaranın% 90'ı, jenerik olmayan şeylerle .NET 1'in varlığından geliyor gibi görünüyor ... –

İlgili konular