簡體   English   中英

如何轉換通用列表 <T> 到基於接口的列表 <T>

[英]How to convert a generic List<T> to an Interface based List<T>

我確信我遺漏了一些簡單的東西,但是我試圖將所有實現接口的強類型對象列表轉換為該接口類型的列表。

下面是一個演示錯誤的示例:

public void ExampleCode(){
    List<Cube> cubes = new List<Cube>();
    List<Shape> allShapes;
    allShapes = cubes;//Syntax Error
    allShapes = (List<Shape>)cubes;//Syntax Error  
}

public class Cube : Shape
{
    public int ID { get; set; }
    public int Sides { get; set; }
}

public interface Shape
{
  int ID { get; set; }
  int Sides { get; set; }
}

嘗試:而不是像那樣投射

allShapes = cubes.Cast<Shape>().ToList();

你需要.NET 3.5。 我相信Cast擴展方法可以在System.Linq中找到。

你不能。 因為List<T>ILIst<T>只支持不變類型參數。 這歸結為T既用於輸入和輸出參數(例如返回值)。 否則你可以打破類型安全。

其他接口(例如IEntumerable<T> )確實允許一些差異。

有關反對和共同變化的討論,請參閱Eric Lippert的博客“ 編碼中的神奇冒險 ”。 特別是“ 協方差和逆變 ”標簽。

編輯,剛剛添加到“C#常見問題”博客: Covariance和Contravariance FAQ

您所指的是通用協方差,並且不受c#3支持。但是,它受到c#4(.NET 4 / VS 2010)的支持,您可以在此處閱讀更多相關內容:

通用接口的方差

話雖如此, IList<T>不是協變的(因為它接受並暴露了T )。 另一方面, IEnumerable<T>是協變的(因為它不接受T )。

你不能這樣做,因為通過這種方式鑄造你可能會失去所有類型的安全性。 對於instnce,將List<Shape>List<object>將導致任何類型的對象都可以添加到列表中,這將完全不一致。

你也可以這樣做:

allShapes = cubes.ConvertAll(x => (Shape)x);

或者如果你在.NET 2.0中這樣做:

allShapes = cubes.ConvertAll<Shape>(delegate(Cube c){
    return (Shape)c;
});

您不能在類型列表之間進行轉換,即使類型本身是可轉換的。 您需要創建一個新列表並通過迭代原始列表或使用ConvertAll來填充它。 有關示例代碼,請參見http://www.dev102.com/2008/05/15/how-to-convert-listt1-to-listt2/

如果將allShapes定義為IEnumerable,則此方法有效

在C#4.0中,您可以簡單地指定allshapes = cubes

對於C#3.5,您可以使用allShapes = cubes.Select(c =>((Shape)c));

但無論如何你需要使用IEnumerable而不是List

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM