2017-01-29 18 views

答えて

3

すなわち

class PointComparer : IComparer<Point> 
{ 
    private readonly Point referencePoint; 

    public PointComparer(Point referencePoint) 
    { 
     this.referencePoint = referencePoint; 
    } 
    public Int32 Compare(Point x, Point y) 
    { 
     // Compare using referencePoint 
    } 
} 

使用法:

var ordered = myList.OrderBy(x => x, new PointComparer(calculatedReferencePoint)); 

私はOrderyByを使用後者が詐欺であるため、Sortではありません私たちがドキュメントを参照するときは、安定した並べ替えをしていません。

+0

まさに私が探していたもの、ありがとう! –

+0

また、_class_タイプの 'Comparer 'から派生させることもできます。 'Compare(Point、Point)'メソッド(今度は、基底クラスから継承した 'abstract'メソッドの' override')が必要ですが、IComparer と古いものジェネリックでないIComparer。 –

+0

'OrderBy'を使うと、カスタムクラスをスキップし、' Comparison 'デリゲート(lambda)でその参照ポイントをキャプチャ(クローズ)することもできます。これは 'myList.OrderBy(x =>/* xとcomputedReferencePoint * /を含む式)'になります。比較者が本当に必要な場合は、 'Comparer .Create(x =>/* expression for x and computedReferencePoint * /)'のように 'Create'を使って取得することができます。これにより、カスタムクラスを自分で書く必要がなくなります。 –

1

あなたには2つのオプションがあります。

オプション

基準点は、あなたのPointオブジェクトの一部でなければなりません。したがって、PointのCompareメソッドでは、角度を計算してオブジェクトを比較するために考慮する必要があります。

public int IComparer.Compare(Point x, Point y) { 
    var angleX = Utilities.CalculateAngle(x.ReferencePoint); 
    var angleY = Utilities.CalculateAngle(y.ReferencePoint); 

    if (angleX < angleY) return -1; 
    if (angleX == angleY) return 0; 
    if (angleX > angleY) return 1; 

    // Or simply "return angleX - angleY;" 
} 

オプションB Angleが既にあなたのポイントで計算されなければならない

Pointを不変構造にし、構造のインスタンス化時の角度を計算します。その後、そのプロパティーはOrderByとなります。あなたが事前に基準点を計算し、あなたのIComparerのコンストラクタに渡すことができ

public struct Point 
{ 
    public double Angle { get; private set; } 

    public Point(double referencePoint, double x, double y) 
    { 
    // TODO: Calculate Angle 
    } 
} 

points.OrderBy(p => p.Angle); 
+0

**オプション** IComparer.Compareは、すべてのパスの戻り値ではないため、コンパイルエラーを引き起こします。 – PetSerAl

+0

k、コードでコメントした通りに 'return angleX - angleY;'だけを返します。 –

+0

角度は浮動小数点型ではありませんか? AFAIKは、暗黙的にint型に変換されていません。だから、あなたはまだここでエラーがあります。 – PetSerAl

関連する問題