8

適用されているコレクションに null エントリがないにもかかわらず、カスタム IComparer 実装で null オブジェクトを受け取ります。私の理解では、これは IComparer 実装の不一致が原因である可能性があります。次のコードでは、これがどこで発生しているのかわかりません。

参考までに、これらは最初に「正しい」プロパティで並べ替えられ、同じ場合は「tiebreakerDelta」プロパティに基づいて並べ替えられます。

        public int Compare(IFoolsSortable a, IFoolsSortable b)
    {
        int value1 = a.correct;
        int value2 = b.correct;

        // compare the total correct first
        if (value1 < value2) return 1;
        if (value1 > value2) return -1;

        // total correct is the same, sort on deltas (closest without going over)
        value1 = a.tiebreakerDelta;
        value2 = b.tiebreakerDelta;

        // returning -1 says "put value1 higher in the list than value2" 
        // (higher means closer to the 0 element of the sorted array) 
        if (value1 == 0) return -1; // a zero is higher than anything! 
        if (value2 == 0) return 1; // ditto, for the other arg, if val1 isn't zero 
        if (value1 == value2) return 0; // after that, if they are the same, say so 
        // if both are negative, then the larger one goes higher 
        if (value1 < 0 && value2 < 0) return (value1 > value2) ? -1 : 1;
        // if only one is negative, it goes higher 
        if (value1 < 0) return -1;
        if (value2 < 0) return 1;
        // finally, if both are postitive, lower one goes higher 
        return (value1 > value2) ? 1 : -1;
    }

あなたが提供できるかもしれない助けをありがとう!

編集:これは真のヌル参照ではなく、矛盾が原因であると確信しています。また、時折、確認のためにこのエラー テキストが表示されます -

Unable to sort because the IComparer.Compare() method returns inconsistent results. Either a value does not compare equal to itself, or one value repeatedly compared to another value yields different results. x: '',  x's type: 'ResultsLineViewModel',

残念ながら、ブレークポイントはこれで役に立ちません。

編集:これは、ResultsLineViewModel が IFoolsSortable インターフェイスを実装する短い例です。

List<ResultsLineViewModel> ls = new List<ResultsLineViewModel>();
        ResultsLineViewModel line1 = new ResultsLineViewModel();
        line1.correct = 10;
        line1.tiebreakerDelta = 0;
        ls.Add(line1);

        ResultsLineViewModel line2 = new ResultsLineViewModel();
        line2.correct = 10;
        line2.tiebreakerDelta = 2;
        ls.Add(line2);

        ResultsLineViewModel line3 = new ResultsLineViewModel();
        line3.correct = 10;
        line3.tiebreakerDelta = -3;
        ls.Add(line3);

        ResultsLineViewModel line4 = new ResultsLineViewModel();
        line4.correct = 9;
        line4.tiebreakerDelta = 0;
        ls.Add(line4);

        ls.Sort(new FoolsSort());

この場合の正しい並べ替えは、Line1、line3、line2、line4 です。

4

1 に答える 1

18

aより大きい場合bCompare(a,b)1 を返し、 Compare(b,a)-1 を返す必要があります。、およびa.correct = b.correct両方がある場合、操作の順序を保持する必要があるため、これはメソッドと一貫性がありません。a.tiebreakerDelta = 0b.tiebreakerDelta = 0Compare

私が見る限り、最初にこれを行う必要があります

if (value1 == value2) return 0; // after that, if they are the same, say so

そしてこれ:

if (value1 == 0) return -1; // a zero is higher than anything! 
if (value2 == 0) return 1; // ditto, for the other arg, if val1 isn't zero 

また、ロジックが逆になっていることに注意してください。最初の値が 2 番目の値より大きい場合は、-1 ではなく 1 を返す必要があります。たとえば、このリンクを確認してください

于 2012-11-15T22:45:04.247 に答える