C# 使用 lambda 表达式代替 IComparer 参数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16839479/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Using lambda expression in place of IComparer argument
提问by haughtonomous
Is it possible with C# to pass a lambda expression as an IComparer argument in a method call?
C# 是否可以在方法调用中将 lambda 表达式作为 IComparer 参数传递?
eg something like
例如像
var x = someIEnumerable.OrderBy(aClass e => e.someProperty,
(aClass x, aClass y) =>
x.someProperty > y.SomeProperty ? 1 : x.someProperty < y.SomeProperty ? -1 : 0);
I can't quite get this to compile so I'm guessing not, but it seems such an obvious synergy between lambdas and anonymous delegates that I feel I must be doing something foolishly wrong.
我不能完全编译它,所以我猜不是,但是 lambdas 和匿名委托之间似乎有如此明显的协同作用,我觉得我一定是在做一些愚蠢的错误。
TIA
TIA
采纳答案by Timothy Shields
As Jeppe points out, if you're on .NET 4.5, you can use the static method Comparer<T>.Create.
正如 Jeppe 指出的那样,如果您使用的是 .NET 4.5,则可以使用静态方法Comparer<T>.Create。
If not, this is an implementation that should be equivalent:
如果不是,这是一个应该等效的实现:
public class FunctionalComparer<T> : IComparer<T>
{
private Func<T, T, int> comparer;
public FunctionalComparer(Func<T, T, int> comparer)
{
this.comparer = comparer;
}
public static IComparer<T> Create(Func<T, T, int> comparer)
{
return new FunctionalComparer<T>(comparer);
}
public int Compare(T x, T y)
{
return comparer(x, y);
}
}
回答by Jeppe Stig Nielsen
If you're on .NET 4.5, you can use the static method Comparer<aClass>.Create.
如果您使用的是 .NET 4.5,则可以使用静态方法Comparer<aClass>.Create。
Documentation: Comparer<T>.CreateMethod .
Example:
例子:
var x = someIEnumerable.OrderBy(e => e.someProperty,
Comparer<aClass>.Create((x, y) => x.someProperty > y.SomeProperty ? 1 : x.someProperty < y.SomeProperty ? -1 : 0)
);
回答by Douglas
If you consistently want to compare projected keys (such as a single property), you can define a class that encapsulates all the key comparison logic for you, including null checks, key extraction on both objects, and key comparison using the specified or default inner comparer:
如果您一直想比较投影键(例如单个属性),您可以定义一个类为您封装所有键比较逻辑,包括空检查、两个对象的键提取以及使用指定或默认内部的键比较比较器:
public class KeyComparer<TSource, TKey> : Comparer<TSource>
{
private readonly Func<TSource, TKey> _keySelector;
private readonly IComparer<TKey> _innerComparer;
public KeyComparer(
Func<TSource, TKey> keySelector,
IComparer<TKey> innerComparer = null)
{
_keySelector = keySelector;
_innerComparer = innerComparer ?? Comparer<TKey>.Default;
}
public override int Compare(TSource x, TSource y)
{
if (object.ReferenceEquals(x, y))
return 0;
if (x == null)
return -1;
if (y == null)
return 1;
TKey xKey = _keySelector(x);
TKey yKey = _keySelector(y);
return _innerComparer.Compare(xKey, yKey);
}
}
For convenience, a factory method:
为方便起见,工厂方法:
public static class KeyComparer
{
public static KeyComparer<TSource, TKey> Create<TSource, TKey>(
Func<TSource, TKey> keySelector,
IComparer<TKey> innerComparer = null)
{
return new KeyComparer<TSource, TKey>(keySelector, innerComparer);
}
}
You could then use this like so:
然后你可以像这样使用它:
var sortedSet = new SortedSet<MyClass>(KeyComparer.Create((MyClass o) => o.MyProperty));
You can refer to my blog postfor an expanded discussion of this implementation.
您可以参考我的博客文章,以进一步讨论此实现。

