【问题标题】:How to cast to generic collection如何转换为通用集合
【发布时间】:2012-03-19 13:58:06
【问题描述】:

我有一个通用集合路径,其中 T 是 Segment - Segment 是抽象类。 我有一个 Path 的派生类 ClosedPath,它包含来自抽象基类 Segment 通过中间类 LineSegment 的派生类 SpecialLineSegments。 我正在尝试选择满足条件的路径,然后我将对其进行修改,使其可能包含不同类型的段,并且可能不再是 ClosedPath ....所以我正在尝试转换为 Path。编译器给出了这个强制转换是不可能的错误。

       public static void Method1(ClosedPath[] paths)
       {
            bool condition = false;
            //working code..

            Path<Segment> Pslct = new Path<Segment>();
            foreach (ClosedPath P in paths)
            {
                if (condition)
                {
                    //working code

                    Pslct = (Path<Segment>) P;

                }

            }
       }

路径定义如下...

public class Path<T> : IEnumerable<T> where T : Segment
{
    private List<T> segments = new List<T>();

    public List<T> Segments 
    {  
        set { segments = value;}
        get { return this.segments; } 
    }

    public T this[int pos]
    {
        get { return (T)segments[pos]; }
        set { segments[pos] = value; }
    }

    public Path()
    {
      this.Segments = new List<T>();   
    }

    public Path(List<T> s)
    {
        this.Segments = s;
    }

    public void AddSegment(T s) {Segments.Add(s);}

    public int Count {get {return Segments.Count;}}

    IEnumerator<T> IEnumerable<T>.GetEnumerator()
    { return Segments.GetEnumerator();}
    IEnumerator IEnumerable.GetEnumerator()
    { return Segments.GetEnumerator(); }
}

ClosedPath 派生自

  public class LinePath<T> : Path<T>, IEnumerable<T> where T : LineSegment
  {
       //working code
  }

LineSegment 派生自 Segment

【问题讨论】:

  • 写一个显式的转换操作符。
  • 我认为我可以做到这一点,但我也认为显式转换运算符仅适用于不相关的类(通过继承)。我会认为我的两个路径 Path 和 ClosedPath 是通过继承相关的。
  • ClosedPath的基类是什么?
  • 从 Path 派生的泛型类....将在上面进行编辑。
  • 我正在使用 Visual Studio 2010...所以不确定。

标签: c# generics casting abstract-class


【解决方案1】:

由于List&lt;T&gt;,您不能从ClosedPath (Path&lt;LineSegment&gt;) 转换为Path&lt;Segment&gt;
例如:

List<Segment> foo = new List<LineSegment>(); //Will not compile

如果您要直接转换,您可以有一个Path&lt;Segment&gt;,它在内部是一个ClosedPath。这将导致AddSegment(Segment s) 失败,因为它会尝试将Segment s 添加到内部List&lt;LineSegment&gt;。因此,转换时必须强制转换内部List。

if (condition)
{
    //working code

    // Convert the ClosedPath LineSegments to Sements to create the Path<Segment>
    Pslct = new Path<Segment>(P.Cast<Segment>().ToList());

假设 ClosedPath : LinePath&lt;LineSegment&gt; 您应该能够使用 LINQ .Cast&lt;&gt;()

Path<Segment> Pslct = paths.Cast<Path<Segment>>();

【讨论】:

  • 是的。我没有 LINQ 经验....也许我应该快速阅读 LINQ。
  • 对此进行了深入研究 - .Cast 不起作用。编辑答案。
  • 显式转换解决方案已编译,但在运行时测试之前还有一些其他事情要做。
  • 由于List&lt;T&gt; 是不变的,这会给这些类之间的转换带来麻烦。在我使用提供的代码 sn-ps .Cast 运行一些测试后,无法按预期工作 - 您可能需要手动进行转换(见上文)
猜你喜欢
  • 1970-01-01
  • 2010-10-16
  • 2017-11-28
  • 2017-12-24
  • 2010-12-15
  • 1970-01-01
  • 1970-01-01
  • 2018-01-26
相关资源
最近更新 更多