2010-11-04 33 views
1

我試圖從通用列表中獲取某個索引編號的項目編號,我得到:無法投射類型爲「System.Collections.Generic.List 1[typename]' to type 'System.Collections.Generic.List 1 [System 。目的]'。錯誤。從通用列表獲取索引項拋出錯誤

我想要實現的是循環(向前或向後)到基於繼承的基類的某個列表;像這樣(或類似的東西反正):

public class Fruit 
{ 
    public string Name {get;set;} 
} 
public class Apple : Fruit 
{ 
    public bool IsSour {get;set;} 
} 
public class Orange : Fruit 
{ 
    public bool Juicy {get;set;} 
} 
public List<Apple> Apples = new List<Apple>(); 
public List<Orange> Oranges = new List<Oranges>(); 

想什麼,我到是這樣的:

public string[] BuildList(object GenericListHere, bool Backwards) 
{ 
    for(int i=GenericListHere.Length-1;i>=0;i--) 
    { 
    string MyName = GenericListHere[i].Name; 

上面有所pseudocoded,但我想要麼扔在蘋果或橙子名單得到結果。 我不事先知道哪一個對象我得到,所以我得到這樣的(未psuedocoded)計算/長度,其中TestObj就是我得到的對象:

int iBound = -1; 
try 
{ 
    System.Reflection.PropertyInfo oInfo = TestObj.GetType().GetProperty("Count"); 
    iBound = (int)oInfo.GetValue(TestObj, null); 
} 
catch 
{ 

而且如果iBound> = 0這是一個集合。接下來的部分..我多少有些失落......

if (iBound != -1) 
{ 
     int iLoopStart = (backwardsLoop ? iBound - 1 : 0); 
     int iLoopEnd = (backwardsLoop ? -1 : iBound); 
     int iLoopDifference = (backwardsLoop ? -1 : +1); 
     for (int iLoop = iLoopStart; iLoop != iLoopEnd; iLoop += iLoopDifference) 
     { 
      // THIS IS REALLY BAD CODED.. BUT I DONT GET IT 
      object VarCollection = TestObj; 
      object[] arInt = new object[1]; 
      arInt.SetValue(iLoop, 0); 
      Type[] tArray = new Type[1]; 
      tArray.SetValue(typeof(int), 0); 
      object oElem = ((System.Collections.Generic.List<object>)VarCollection)[iLoop]; 

我真正喜歡的是一樣的東西:VarCollection [ILOOP],但是這似乎並沒有工作..

任何人有這些列表的經驗嗎? TIA!

回答

0

只需將它投射到IList並使用索引器。

+0

仍然需要知道演員的正確類型。 – riffnl 2010-11-04 10:12:51

+0

@riffnl:不,你不知道。或者請解釋你爲什麼會這麼想。 – leppie 2010-11-04 10:14:32

+0

「因爲編譯器這麼說」我的答案肯定會是......但是使用System。集合似乎做了這個伎倆。 – riffnl 2010-11-04 10:17:09

1

我真的覺得反思並不是這裏的答案;仿製藥應該足夠滿足您的需求。它似乎也不是實際上需要通過索引從列表中訪問元素,因爲意圖似乎僅僅是將一系列水果投影到一系列水果名稱。如果你需要通過索引訪問元素(例如,如果你堅持使用for循環),如果你使用泛型,它不應該是一個問題; IList<T>上的索引器以及其Count屬性很容易在通用代碼中發現。

下面的解決方案,它使用通用約束,應該可以正常使用.NET 3.5:

public static string[] BuildList<T>(IList<T> list, bool backwards) 
    where T : Fruit 
{ 
    var names = list.Select(fruit => fruit.Name); 
    return (backwards ? names.Reverse() : names).ToArray(); 
} 

在.NET 4.0中,List<Apple>被正確識別爲IEnumerable<Fruit>。因此,下面的簽名應太:

public static string[] BuildList(IEnumerable<Fruit> list, bool backwards) 

在另一方面,你可能要考慮返回一個IEnumerable<string>代替,讓來電者推結果到一個數組,如果它希望這樣。

+0

這個名字是一個簡單的例子。我需要對對象本身做更多的事情,但我不知道我得到的是什麼列表。 – riffnl 2010-11-04 10:12:12

0

在您有object和反思工作的情況下,你應該簡單地使用非通用IList/ICollection接口,而不是一般的IList<T>/ICollection<T>/List<T>;你仍然會有索引器,迭代,添加等。

+0

我想知道爲什麼人們忘了這件事...... – leppie 2010-11-04 09:24:57

+0

唉,我沒有什麼可說的。我沒有構建我正在使用的對象的基礎;我只是在它們被傳遞時纔得到這些對象。 – riffnl 2010-11-04 10:14:41

+0

@riffnl - 但他們仍然* * IList'等,不管他們自己描述爲什麼。只需投... – 2010-11-04 10:24:37