运算符重载多态性返回泛型集合
本文关键字:泛型 集合 返回 多态性 重载 运算符 | 更新日期: 2023-09-27 18:28:07
我想重载+运算符,用于将段添加到一起以形成Path。我定义了一个Path,其中T是Segment,并包含一个List(其中T自然是Segment)。Segment是各种类型Segment的抽象基类,即LineSegment
我有一个重载方法Connected,它检查段是否有一个公共端点。我想在抽象Segment类中定义2个Segment的重载,然后在各自的派生类中定义不同类型的重载,即Segment和LineSegment。
public static Path<T> operator +(Segment s1, Segment s2)
{
if (s1.Connected(s2))
{
List<Segment> slist = new List<Segment>();
slist.Add(s1);
slist.Add(s2);
Path<T> p = new Path<T>(slist);
return p;
}
else
{
return null;
}
}
@Jon
所以本质上。。。
我试图替换以下代码(path1是Path,Segments是List,其中T是Segment)。
Path<T> path1 = new Path<T>(s1);
path1.Segments.Add(s2);
带有
Path<T> path1 = s1 + s2;
问题是使用的代码无法编译。
由于C#不支持泛型运算符,我认为没有简单的方法可以做到这一点。但我可以想象有几种方法可以让它发挥作用:
-
不要这样做。正如Jon所建议的,即使添加两个
LineSegment
,也可以始终返回一个Path<Segment>
。我不喜欢这种"解决方案",因为这可能意味着你必须在所有地方使用强制转换。 -
将运算符添加到从
Segment
继承的每个类型中。这意味着重复代码,但我认为这是最好的选择。例如,LineSegment
的运算符如下所示:public static Path<LineSegment> operator +(LineSegment s1, LineSegment s2)
-
不要将两个线段添加在一起,而是将它们添加到一个空路径中。如果你这样做,最好是让
Path
不可变:var path = Path<LineSegment>.Empty + lineSegment1 + lineSegment2;
-
使用奇怪的重复模板模式的变体:
class SegmentBase<T> where T : SegmentBase<T> { public static Path<T> operator +(SegmentBase<T> s1, SegmentBase<T> s2) { return new Path<T>(new List<T> { (T)s1, (T)s2 }); } } class LineSegment : SegmentBase<LineSegment> { }
如果你这样做,你就不会有任何重复,但这感觉像是一个破解,它可能会使你的继承层次结构复杂化很多(你不能从指定
T
的类继承)。我不喜欢这种解决方案。