繁体   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