我想重载+运算符以将段添加到一起以形成Path。 我已经定义了一个Path,其中T是Segment并包含一个List(其中T自然是Segment)。 Segment是各种类型Segment的抽象基类,即LineSegment
我有一个重载方法Connected,它检查段是否有一个公共端点。我想在抽象的Segment类中为2个Segments定义重载,然后在不同的派生类中为不同的类型定义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
基本上......
我试图替换以下代码(路径1是路径,分段是列表,其中T是段)。
Path<T> path1 = new Path<T>(s1);
path1.Segments.Add(s2);
带
Path<T> path1 = s1 + s2;
问题是代码无法编译。
答案 0 :(得分:1)
由于C#不支持泛型运算符,我认为没有简单的方法可以做到这一点。但我可以想象几种方法让它发挥作用:
不要这样做。正如Jon建议的那样,即使你添加了两个Path<Segment>
,你总是可以返回LineSegment
。我不喜欢这个“解决方案”,因为它可能意味着你必须在整个地方使用演员阵容。
将运算符添加到从Segment
继承的每个类型。这意味着重复代码,但我认为这是最好的选择。例如,LineSegment
的运算符将如下所示:
public static Path<LineSegment> operator +(LineSegment s1, LineSegment s2)
不要将两个段一起添加,而是将它们添加到空路径中。如果你这样做,那么最好是Path
不可变:
var path = Path<LineSegment>.Empty + lineSegment1 + lineSegment2;
使用curiously recurring template pattern的变体:
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
的类继承)。我不喜欢这个解决方案。