2012-07-11 83 views
18

我搞砸泛型和IEnumerable abit,但我好心卡住了。 這是我想要做的: 我想有一個方法返回任何集合類型 - 實現IEnumerable(?) - (例如:List,Stack,Queue,...)返回一個通用的IEnumerable <T>

此外,我希望能夠返回任何數據類型的集合類型。 ,所以我想這個方法能夠返回一個List<string>,以及一個Stack<int>,以及一個List<double> ...等等等等

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

這是我到目前爲止已經試過。然而,這並不工作,我得到這個錯誤:但是

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

,如果我在方法簽名更換IEnumerable<T>IEnumerable<int>,我可以返回一個int類型的任何集合。然而,這意味着,現在我不能返回ListOfStrings了。

會喜歡你需要一個generic type parameter添加到您的方法有任何建議或想法:)

回答

26

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

類型參數在方法名之後,但在參數之前。也可以有一個具有多個類型參數的方法。

當你調用的方法,你可以指定類型:

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

感謝,這工作確實,但現在我似乎無法添加任何東西到堆棧..stackOfInts.Push(3);如果我嘗試這個,它會說:「最好的重載比賽..有一些無效的參數」。有任何想法嗎? – Thousand 2012-07-11 21:08:06

+0

@JaneDoe:你只能添加'T'到'Stack '。 3不一定是'T'。除非你添加[泛型約束](http://msdn.microsoft.com/en-us/library/d5x73970.aspx),否則你不知道'T'是什麼,所以你甚至不能構建一個 - 要做到這一點,你需要一個'new()'約束。你想做什麼,爲什麼你需要這個? – 2012-07-11 21:10:07

+1

我不需要這個特別的東西,我只是嘗試了一堆東西。但我現在明白了,謝謝。 – Thousand 2012-07-11 21:12:11

10

訣竅是聲明<T>吧,如果你定義通用<T>,那麼你必須堅持下去你的方法,使如果你有IEnumerable<T>然後在你的方法的其他地方,你必須使用<T>而不是<int>或任何其他類型。

只有後者,當你實際上使用你泛型類型你替代泛型<T>爲一個真正的類型。

查看示例

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

是,如果你改變我Enumerable<T> to IEnumerable<dynamic>

這樣你可以返回任何類型:

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

爲什麼要使用泛型,如果你打算把類型安全性扔出窗外... – Adam 2012-07-11 21:15:47

+0

這確實看起來有點像黑客..我試了一下,它也沒有編譯。 – Thousand 2012-07-11 21:16:26

+0

@codesparkle我同意你的觀點並強烈關注它,但他們是你無法控制給定的第三方API方法返回類型的時候,所以動態是這種情況下的救星 – HatSoft 2012-07-11 21:18:41

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

類型參數需要通過指定來電者的地方。

要麼實例化一個泛型類時:

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()) 
{ 
} 

或調用非泛型類的泛型方法時:

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>()) 
{ 
} 
相關問題