C# 树中的泛型
我有一个segment类,它是树中的一个节点。没有树类。这棵树只是由几段组成的C# 树中的泛型,c#,generics,tree,C#,Generics,Tree,我有一个segment类,它是树中的一个节点。没有树类。这棵树只是由几段组成的 public abstract class Segment { public List<Segment> Descendants { get; } => new List<Segment> Descendants; public abstract SegmentVisual VisualRepresentation { get; } } 与片段一样,该视觉对象也有子对
public abstract class Segment
{
public List<Segment> Descendants { get; } => new List<Segment> Descendants;
public abstract SegmentVisual VisualRepresentation { get; }
}
与片段一样,该视觉对象也有子对象,因此可以将单个视觉对象添加到屏幕以绘制自身及其所有子对象
下面是一个实现:
public class LineSegment : Segment
{
public LineSegment()
{
this.VisualRepresentation = new LineSegmentVisual(this);
}
public override SegmentVisual VisualRepresentation { get; }
public Pen Stroke { get; set; }
}
我的问题是最后一节课。你可以看到重新竖琴的建议。而且我一直都觉得向下投射的感觉不太好。如果我必须在其他地方找到它的主人,我将不得不沮丧地再次获得Stroke属性
如果我将SegmentVisual设置为generic SegmentVisual,其所有者为T,则会引入一个新的障碍,因为现在SegmentVisual只能包含SegmentVisual的后代,这不应该是这样,因为我希望它包含任何类型的SegmentVisual,我只希望所有者是强类型的
我只希望SegmentVisual能够对应于特定的类,以便其所有者属性是强类型的。我似乎无法理解这一点 您可以使用new在子类中声明强类型所有者:
public class LineSegmentVisual : SegmentVisual
{
new LineSegment Owner { get { return (LineSegment)base.Owner; } }
public LineSegmentVisual(Segment owner)
: base(owner)
{
}
public override void RedrawItself()
{
using (DrawingContext ctx = this.RenderOpen())
{
var owner = this.Owner;
ctx.DrawLine(owner.Stroke, this.Owner.Position, this.Owner.ControlPointPos);
}
}
}
这样,每次调用此.Owner时,都将铸造base.Owner,但至少可以避免重复代码
第二种方法是使用继承。使用基本功能声明SegmentVisual
abstract class SegmentVisual
{
public List<SegmentVisual> Descendants { get; private set; }
...
}
Owner可以在子类中使用,而无需强制转换,公共功能只需使用SegmentVisual即可
第三种方法是使用泛型协方差,但必须为类型声明接口:
public class Program
{
public static void Main()
{
var sv = new LineSegmentVisual();
sv.Descendants = new List<ISegmentVisual<Segment>> { new SquareSegmentVisual() };
}
}
abstract class Segment {}
class LineSegment : Segment {}
class SquareSegment: Segment {}
interface ISegmentVisual<out TOwner>
{
TOwner Owner { get; }
List<ISegmentVisual<Segment>> Descendants { get; }
}
class LineSegmentVisual : ISegmentVisual<LineSegment>
{
public LineSegment Owner { get; set; }
public List<ISegmentVisual<Segment>> Descendants { get; set; }
}
class SquareSegmentVisual : ISegmentVisual<SquareSegment>
{
public SquareSegment Owner { get; set; }
public List<ISegmentVisual<Segment>> Descendants { get; set; }
}
希望,这会有所帮助。C不支持返回类型差异。也就是说,以下情况是不可能的:
class Foo
{
virtual Base Owner{ get; }
}
class Bar: Foo
{
override Derived Owner { get; } // where Dervided: Base
}
您将得到一个编译时错误,通知您派生的方法不会覆盖任何合适的方法。老实说,我发现C中缺少这个功能有点恼人,尽管它在未来的版本中已经上线几次了,但它从来没有成功过。老实说,竞争的功能已经更新了很多,更加有趣和有用
在我看来,你有两个合理的选择。一种是隐藏所有者:
另一种是使用显式实现的接口:
interface IOwnable
{
Base Owner { get; }
}
class Foo: IOwnable
{
Base IOwnable.Owner { get; }
}
class Bar: Foo
{
Derived Owner { get { return ((IOwnable)base).Owner as Derived; } // where Derived: Base
}
谢谢,今晚晚些时候我会看一看并通知你:我使用了第二种方法,它解决了问题。感谢s:
public class Program
{
public static void Main()
{
var sv = new LineSegmentVisual();
sv.Descendants = new List<ISegmentVisual<Segment>> { new SquareSegmentVisual() };
}
}
abstract class Segment {}
class LineSegment : Segment {}
class SquareSegment: Segment {}
interface ISegmentVisual<out TOwner>
{
TOwner Owner { get; }
List<ISegmentVisual<Segment>> Descendants { get; }
}
class LineSegmentVisual : ISegmentVisual<LineSegment>
{
public LineSegment Owner { get; set; }
public List<ISegmentVisual<Segment>> Descendants { get; set; }
}
class SquareSegmentVisual : ISegmentVisual<SquareSegment>
{
public SquareSegment Owner { get; set; }
public List<ISegmentVisual<Segment>> Descendants { get; set; }
}
class Foo
{
virtual Base Owner{ get; }
}
class Bar: Foo
{
override Derived Owner { get; } // where Dervided: Base
}
class Bar: Foo
{
new Derived Owner { get { return base.Owner as Derived; } // where Derived: Base
}
interface IOwnable
{
Base Owner { get; }
}
class Foo: IOwnable
{
Base IOwnable.Owner { get; }
}
class Bar: Foo
{
Derived Owner { get { return ((IOwnable)base).Owner as Derived; } // where Derived: Base
}