簡體   English   中英

為什么對泛型列表進行顯式強制轉換不起作用

[英]why does explicit cast for generic list not work

我正在嘗試為派生類IntersectionPath構造一個對象內的對象列表,如下所示。

    public class IntersectionPath : Path<IntersectionSegment>, IEnumerable
    {          

        //Constructors
        public IntersectionPath() : base() {  Verts = null; }

        public IntersectionPath(List<Intersection> inVerts, List<Segment<Node>> inEdges) : base() 
        {
            this.Segments = (List<IntersectionSegment>) inEdges;
        }

    }

細分是在通用基類Path中定義的

    public class Path<T> : IEnumerable<T> where T : Segment<Node>
    {   
        //public properties
        public List<Direction> Directions {get; set; }
        public List<T> Segments  {  get; set; }
    }

我已經為IntersectionSegment類中的轉換定義了一個顯式運算符(請參閱下文,因此不清楚為什么不進行編譯。我在IntersectionPath構造函數中有一個錯誤消息用於轉換。

public class IntersectionSegment : Segment<Intersection>
{           
    //curves which intersect the primary curve at I0(Start Node) and I1(End Node)
    public Curve C0 { get; set; }
    public Curve C1 { get; set; }

    public IntersectionSegment():base() {}

    public IntersectionSegment(Intersection n0, Intersection n1):base(n0,n1){}

    public static explicit operator IntersectionSegment(Segment<Node> s)
    {
        if ((s.Start is Intersection) && (s.End is Intersection))
        {
            return new IntersectionSegment(s.Start as Intersection,s.End as Intersection);
        }
        else return null;
    }

    public static explicit operator List<IntersectionSegment>(List<Segment<Node>> ls)
    {
        List<IntersectionSegment> lsout = new List<IntersectionSegment>();
        foreach (Segment<Node> s in ls)
        {
            if ((s.Start is Intersection) && (s.End is Intersection))
            {
                lsout.Add(new IntersectionSegment(s.Start as Intersection,s.End as Intersection));
            }
            else return null;
        }
        return lsout;
    }

細分定義為:

public class Segment <T> : Shape where T : Node
{
    //generic properties
    public T Start { get; set; }
    public T End { get; set; }

 }

List<InteractionSegment>InteractionSegment 將一種類型的列表轉換為另一種類型的列表不會轉換每個項目。
您需要執行以下操作:

this.Segments = inEdges.Select(x => (InteractionSegment)x).ToList();

這使用LINQ to Objects將inEdges中的每個對象inEdges轉換為InteractionSegment對象,並將結果放回到列表中,然后分配給this.Segments

讓我們看一個不那么混亂的例子。

class Animal {}
class Giraffe : Animal {}
class Tiger : Animal {}
...
List<Giraffe> giraffes = new List<Giraffe>();
List<Animal> animals = (List<Animal>) giraffes; // illegal

您的問題是,我相信“為什么在最后一行進行強制轉換是非法的?”

讓我們假設這是合法的。 現在我們添加另一行:

animals.Add(new Tiger());

您可以將老虎添加到動物列表中,對嗎? 但是那只動物名單實際上是一只長頸鹿名單 演員表不會復制該列表,而是說“我想將此對象視為這種類型”。 但是由於這樣做會讓您做瘋狂的事情,例如將老虎放入長頸鹿名單中,因此我們將演員陣容定為非法。

您的情況只是同一情況的復雜得多。

幾乎每天都會在StackOverflow上問這個問題。 尋找“協方差和自變量”,您會發現許多示例。

它不僅僅因為List<Segment<Node>>不是List<IntersectionSegment>而起作用。 如果要創建更高版本,則可以使用Cast()將列表中的每個項目顯式轉換為所需的類型:

this.Segments = inEdges.Cast<IntersectionSegment>().ToList();

暫無
暫無

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

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