使用float + Lambda表达式C#

Mat*_*Mat 4 c# lambda

var distances = new Dictionary<char, float>();
var nodes = new List<char>();
Run Code Online (Sandbox Code Playgroud)

我有这条线找到最小的距离

nodes.Sort((x, y) => distances[x] - distances[y]);
Run Code Online (Sandbox Code Playgroud)

当我使用int它时效果很好,但是当我使用时,float我收到了一条消息

无法将lambda表达式转换为类型'System.Collections.Generic.IComparer',因为它不是委托类型

你有好主意吗?

Eri*_*ert 10

首先,当值为整数时,原始程序是一种糟糕的编程习惯.它适用于字符,但我会避免这种糟糕的编程习惯.

传递给sort函数的委托必须具有许多属性; 特别是如果x小于y则必须返回负int,如果x大于y则返回正int,如果x大于y则返回0.您的原始lambda不会对整数值执行此操作.(看看你是否可以找到两个整数x和y,使x小于y,但x-y为正.)

代表还必须施加总订单.在总订单中:

  • 传递性必须成立.如果A == B且B == C则A必须等于C.如果A <B且B <C则A必须小于C.依此类推.
  • 它必须是反对称的.也就是说,如果A <B则B> A,依此类推.

减法不符合整数的这些条件.正确的代码是实际编写比较.

nodes.Sort((x, y) => x < y ? -1 : (x > y ? 1 : 0));
Run Code Online (Sandbox Code Playgroud)

如果没有NaN,那么对于字符和浮点数来说效果很好.如果您有NaN,那么您需要做额外的工作来强加总订单.

我还要指出,对字符的这种序数比较通常不是你想要的比较.当然,这将正确地指出e小于z,但简单的序数比较也表示z小于é,这可能不是你想要的.字符排序取决于文化; 你确定要按Unicode委员会刚刚强加的命令订购吗?

有关此主题的更多信息,请参阅我的系列文章; 它从这里开始:

http://ericlippert.com/2011/01/20/bad-comparisons-part-one/


Jon*_*eet 8

你不能将你的lambda表达式转换成一个Comparison<char>(这是你想要的),因为它返回一个float- 你有效地得到了一个Func<char, char, float>,而Comparison<char>更接近Func<char, char, int>.

最简单的方法是使用float.CompareTo:

nodes.Sort((x, y) => distances[x].CompareTo(distances[y]));
Run Code Online (Sandbox Code Playgroud)

或者,如果您不需要就地排序,可以使用LINQ:

var sorted = nodes.OrderBy(x => distances[x]);
Run Code Online (Sandbox Code Playgroud)