2012-07-11 26 views
18

Generics ve IEnumerable abit ile uğraşmaktayım, ama sıkışıp kaldım. İşte ben yapmaya çalışıyorum budur: - (?) Ben herhangi bir koleksiyon türü döndüren bir yöntem olmasını istiyorsanız IEnumerable uygular: -genel bir IEnumerable döndürüyor <T>

ayrıca (şimdiye örn Liste, Stack, Kuyruk, ...), Herhangi bir veri türü için herhangi bir koleksiyon türünü iade edebilmek istiyorum. yüzden bu yöntem bu ben şimdiye kadar denedim budur vs vs

public IEnumerable<T> returnSomething() 
    { 
     Stack<int> stackOfInts = new Stack<int>(); 
     List<string> listOfStrings = new List<string>(); 
     return stackOfInts; 
    } 

... Bir List<double> yanı sıra bir Stack<int> yanı sıra List<string>, dönmek isterler. Bu ancak ben bu hatayı alıyorum, çalışmaz:

Cannot implicitly convert type 'System.Collections.Generic.Stack<int>' to 'System.Collections.Generic.IEnumerable<T>'. An explicit conversion exists (are you missing a cast?) 

ancak ben IEnumerable<int> için yöntem imzası IEnumerable<T> değiştirirseniz, ben int türünde herhangi bir koleksiyonu döndürebilir. Ancak bu, artık ListOfStrings'u iade edemem anlamına geliyor.

Sen yöntemine bir generic type parameter eklemeniz gerekir herhangi bir öneri veya fikir :)

cevap

26

seviniriz:

public IEnumerable<T> ReturnSomething<T>() 
{ 
    Stack<T> stackOfT = new Stack<T>(); 
    return stackOfT; 
} 

tür parametre yöntemi adından sonra görünür, ancak parametrelerin önce. Birden fazla tip parametresi olan bir yönteme sahip olmak da mümkündür.

Eğer yöntemini çağırdığınızda size türünü belirtebilirsiniz:

IEnumerable<int> myInts = ReturnSomething<int>(); 
+0

sayesinde, bu gerçekten de çalışır, ancak şimdi eklemek görünmektedir olamaz stack..stackOfInts.Push (3) için bir şey; Bunu denerseniz, diyor ki: "En iyi aşırı yüklenmiş eşleşme .. bazı geçersiz argümanlar var". herhangi bir fikir? – Thousand

+0

@JaneDoe: Yalnızca 'Yığın ' için 'T's ekleyebilir. 3 mutlaka bir "T" değil. Bir [genel tür kısıtlamasını] ekleyin sürece (http://msdn.microsoft.com/en-us/library/d5x73970.aspx) Bir 't' nedir hiçbir fikrim yok, bu yüzden bile bir inşa edemez - Bunu yapmak için bir 'new()' kısıtlaması gerekir. Ne yapmaya çalışıyorsun ve neden buna ihtiyacın var? –

+1

Özellikle bir şey için buna ihtiyacım yok, sadece bir şeyler deniyorum. Ama şimdi anladım, teşekkürler. pencereden dışarı tür güvenliği atmak için gidiyoruz – Thousand

10

hüner Eğer jenerik <T> tanımlarsanız nedenle, kendi yöntemleri buna sadık kalmak zorunda, sonra,<T> hakkını beyan etmektir IEnumerable<T>, yönteminizin başka bir yerinde varsa, <T> ve <int> veya başka bir tür kullanmanız gerekir. Aslında kullanımı Eğer genel tür gerçek türü için jenerik <T> yerine zaman

Sadece ikincisidir.

böyle I Enumerable<T> to IEnumerable<dynamic>

değiştirirseniz

class Foo<T> 
{ 
    public IEnumerable<T> GetList() 
    { 
     return new List<T>(); 
    } 

    public IEnumerable<T> GetStack() 
    { 
     return new Stack<T>(); 
    } 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     Foo<int> foo = new Foo<int>(); 
     IEnumerable<int> list = foo.GetList(); 
     IEnumerable<int> stack = foo.GetStack(); 

     Foo<string> foo1 = new Foo<string>(); 
     IEnumerable<string> list1 = foo1.GetList(); 
     IEnumerable<string> stack1 = foo1.GetStack(); 
    } 
} 
1

Evet her türlü dönebilirsiniz bir örneğine bakın: tür parametresi tarafından belirtilmesi gerekir

public IEnumerable<dynamic> returnSomething() 
{ 
..... 
+2

neden hiç generic kullanacaksınız ... – Adam

+0

bu gerçekten kesmek biraz gibi görünüyor .. ben de hiç derleme denedim ve. Eğer verilen üçüncü şahıs API yöntemi dönüş türüne kontrole sahip olmadığında – Thousand

+0

@codesparkle Öyle dinamik kurtarıcı yaptığınızda böyle bir durumda – HatSoft

2
public IEnumerable<T> returnSomething() 
{ 
    Stack<int> stackOfInts = new Stack<int>(); 
    return (IEnumerable<T>) stackOfInts; 
} 
1

Arayan bir yerde.olmayan bir jenerik sınıfının genel bir yöntem çağrılırken

public class MyClass<T> 
{ 
    public IEnumerable<T> returnSomething() 
    { 
     Stack<T> stackOfTs = new Stack<T>(); 
     List<T> listOfTs = new List<T>(); 
     return stackOfTs; 
    } 
} 

var v = new MyClass<int>(); 
foreach(var item in v.returnSomething()) 
{ 
} 

Veya: Bir generic sınıfı yaparken

Ya

public class MyClass 
{ 
    public IEnumerable<T> returnSomething<T>() 
    { 
     Stack<T> stackOfTs = new Stack<T>(); 
     List<T> listOfTs = new List<T>(); 
     return stackOfTs; 
    } 
} 


var v = new MyClass(); 
foreach(var item in v.returnSomething<int>()) 
{ 
} 
İlgili konular