2

セグメントを一緒に追加してパスを形成する+演算子をオーバーロードしたい。 私は、Tがセグメントであり、リスト(自然にTがセグメントである)を含むパスを定義しました。セグメントは、さまざまな種類のセグメント、すなわちLineSegmentの抽象基本クラスです。演算子のオーバーロード多型がジェネリックコレクションを返す

オーバーロードされたメソッドConnectedがあり、セグメントに共通のエンドポイントがあるかどうかがチェックされます。抽象セグメントクラスで2つのセグメントのオーバーロードを定義し、次にそれぞれの派生クラス内の異なるタイプ、つまりセグメントとラインセグメントに対してオーバーロードを定義したいと思います。私は、次のコードを交換しようとしている

だから、基本的に...

@ジョン

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; 
    } 
} 

(パス1は、セグメントTはセグメントであるリストで、パスです)。

Path<T> path1 = s1 + s2; 

Path<T> path1 = new Path<T>(s1); 
path1.Segments.Add(s2); 

問題は、コードをコンパイルしていないということです。

+3

何が問題ですか?ところで、あなたの入力値をNULL値と比較してチェックしておらず、実行時に失敗するかもしれません。 –

+1

あなたはまだ問題が何であるか説明しませんでした。あなたの現在のコードは動作しますか?そうでない場合は、エラー、例外などをコンパイルするのは何ですか? – svick

答えて

1

C#は汎用演算子をサポートしていないので、これを行う簡単な方法はないと思います。しかし、私はそれを動作させるいくつかの方法を想像することができます:

  1. これをしないでください。 Jonが提案したように、LineSegmentを2つ追加しても、常にPath<Segment>を返すことができます。私はこの "解決策"が気に入らない。なぜなら、あなたはどこにでもキャストを使わなければならないということになるからだ。

  2. Segmentから継承するすべての型に演算子を追加します。これはコードを繰り返すことを意味しますが、ここではこれが最善の選択だと思います。例えば、LineSegmentためのオペレータは、次のようになります。

    public static Path<LineSegment> operator +(LineSegment s1, LineSegment s2) 
    
  3. 2つのセグメントを追加し、代わりに空のパスにそれらを追加しないでください。あなたがこれを行う場合は、Pathが不変行った場合、それはおそらく最高のようになります。

    var path = Path<LineSegment>.Empty + lineSegment1 + lineSegment2; 
    
  4. 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を指定するクラスから継承することはできません)。私はこの解決策が嫌いです。

+0

ありがとう、今よく理解される。私はあまりにも多くを持っていない2最高のオプション。正直言って私は最初にその方法を選ぶことができましたが、私の子供は理想的なアプローチを知りたがっていました。 varとdynamicは多くポップアップしているようです...これらについて何も知らないことで私は逃しましたか?私は本当に.NET 3までしか知りません。0 – gwizardry

+0

'var'は実際にあなたのコードを変更しません。コードを単純化するので、型のスペルを書く必要はありません(ここでは匿名型は無視されます)。 'dynamic'はコンパイル時の型の変数を持っていても、実行時の型に基づいて演算子を使いたい場合に便利です。たとえば、 'Segment s1 = new LineSegment()、s2 = new LineSegment();'とすると、 's1 + s2'という式は' Segment'の+演算子を実行します。 'LineSegment'の演算子を実行したければ'(dynamic)s1 + s2'を使うことができます。しかし、私はそれがここで非常に有用だとは思わない。 – svick

関連する問題