为什么在List上调用Sort(IComparer)时会出现System.ArgumentException?

sal*_*inx 6 c# sorting exception list

我用自己的IComparer对List进行排序,这在运行应用程序(XNA游戏)一个多小时后效果很好.但是,突然间,我在使用自定义Comparer调用sort-method时有时会出现以下错误:

An unhandled exception of type 'System.ArgumentException' occured in mscorlib.dll
Additional Information: ArgumentException
Run Code Online (Sandbox Code Playgroud)

这是抛出异常的行:

List<Continent> markets = new List<Continent>();
// filling the markets list ...
markets.Sort(new MarketCostCoverComparer(this)); 
Run Code Online (Sandbox Code Playgroud)

这是我的类实现IComparer接口:

class MarketCostCoverComparer : IComparer<Continent> { 

    private Player player; 

    public MarketCostCoverComparer(Player player) { 
        this.player=player; 
    } 

    public int Compare(Continent c1, Continent c2) { 
        if(player.GetCostCovering(c1)<player.GetCostCovering(c2)) { 
            return +1; 
        } else if(player.GetCostCovering(c1)==player.GetCostCovering(c2)) { 
            return 0; 
        } else { 
            return -1; 
        } 
    } 

} 
Run Code Online (Sandbox Code Playgroud)

这里有一些链接到比较器的方法......:

public float GetCostCovering(Continent continent) {
        // cover<1 => bad | cover>1 => good
        if(GetOilfieldTheoreticOutput(continent.Type, true)<continent.Economy.CurrentDemand) {
            return ((float)((GetOilfieldTheoreticOutput(continent.Type, true)*continent.Economy.CurrentPrice)))/(float)GetOilfieldCosts(continent.Type, true);
        } else {
            return ((float)((continent.Economy.CurrentDemand*continent.Economy.CurrentPrice)))/(float)GetOilfieldCosts(continent.Type, true);
        }
    }

public int GetOilfieldTheoreticOutput(ContinentType continent, bool drilled) {
        int total = 0;
        foreach(Oilfield oilfield in worldmap.Continents[(int)continent].Oilfields) {
            if(oilfield.Owner==this && oilfield.Drilled==drilled) {
                total+=oilfield.TheoreticOutput;
            }
        }
        return total;
    }

public int GetOilfieldCosts(ContinentType continent, bool drilled) {
        int total = 0;
        foreach(Oilfield oilfield in worldmap.Continents[(int)continent].Oilfields) {
            if(oilfield.Owner==this && oilfield.Drilled==drilled) {
                total+=oilfield.Costs;
            }
        }
        return total;
    }
Run Code Online (Sandbox Code Playgroud)

这里是例外的截图:

mscorlib.dll中出现未处理的

这里仔细看看Locals/Stack-Trace(这是一个旧截图,但我会尝试在接下来的几个小时内重现这个异常,以便我可以扩展跟踪):

在此输入图像描述

slo*_*oth 5

问题是您的IComparer的实现.它可以返回不一致的结果,因此sort函数将抛出异常.

也许看看这个这个问题的更多信息.

题:

是性能continent.Economy.CurrentDemandcontinent.Economy.CurrentPrice无副作用?

备注:

您的IComparer应该能够处理null.来自文档:

允许将null与任何类型进行比较,并且在使用IComparable时不会生成异常.排序时,null被认为小于任何其他对象.

也许这是一个浮点问题,但这只是一个疯狂的猜测.所以也许你应该用decimal而不是float.