Я, оказалось, видел некоторый код, куда этот парень передал лямбда-выражение ArrayList. Вид (IComparer здесь) или IEnumerable. SequenceEqual (список IEnumerable, IEqualityComparer здесь), где IComparer или IEqualityComparer ожидались.
Я не могу быть уверен, видел ли я его, хотя, или я просто мечтаю. И я, может казаться, не нахожу расширение ни на одном из этих наборов, который принимает Func <> или делегат в их сигнатурах методов.
Есть ли такой метод перегрузки/расширения? Или, в противном случае действительно ли возможно слоняться без дела как это и передать алгоритм (делегат чтения), где интерфейс отдельного метода ожидается?
Обновление Спасибо, все. Это - то, что я думал. Я, должно быть, мечтал. Я знаю, как записать преобразование. Я просто не был уверен, видел ли я что-то как этот или просто думал, что видел его.
Еще один Взгляд обновления, здесь, я нашел один такой экземпляр. Я не мечтал, в конце концов. Посмотрите на то, что этот парень делает здесь. Что дает?
И вот другое обновление: хорошо, я получаю его. Использование парня Comparison
перегрузка.Мило. Хороший, но полностью склонный для введения в заблуждение Вас. Хороший, все же.Спасибо.
Я голосую за теорию сновидений.
Вы не можете передать функцию там, где ожидается объект: производные от System.Delegate (которыми являются лямбды) не реализуют эти интерфейсы.
Вероятно, вы видели использование делегата Converter
, который можно смоделировать с помощью лямбда-выражения. Array.ConvertAll использует экземпляр этого делегата.
Вы не можете передать его напрямую, однако вы можете сделать это, определив класс LambdaComparer
, который исключает Func
, а затем использует его в своем CompareTo
.
Он не такой лаконичный, но вы можете сделать его короче с помощью некоторых творческих методов расширения на Func
.
public class Comparer2<T, TKey> : IComparer<T>, IEqualityComparer<T>
{
private readonly Expression<Func<T, TKey>> _KeyExpr;
private readonly Func<T, TKey> _CompiledFunc
// Constructor
public Comparer2(Expression<Func<T, TKey>> getKey)
{
_KeyExpr = getKey;
_CompiledFunc = _KeyExpr.Compile();
}
public int Compare(T obj1, T obj2)
{
return Comparer<TKey>.Default.Compare(_CompiledFunc(obj1), _CompiledFunc(obj2));
}
public bool Equals(T obj1, T obj2)
{
return EqualityComparer<TKey>.Default.Equals(_CompiledFunc(obj1), _CompiledFunc(obj2));
}
public int GetHashCode(T obj)
{
return EqualityComparer<TKey>.Default.GetHashCode(_CompiledFunc(obj));
}
}
используйте его так
ArrayList.Sort(new Comparer2<Product, string>(p => p.Name));
Вы можете предоставить лямбда-выражение для метода Array.Sort, так как он требует метода, который принимает два объекта типа T и возвращает целое число. . Таким образом, вы можете предоставить лямбду следующего определения (a, b) => a.CompareTo (b)
. Пример сортировки целочисленного массива по убыванию:
int[] array = { 1, 8, 19, 4 };
// descending sort
Array.Sort(array, (a, b) => -1 * a.CompareTo(b));
У этих методов нет перегрузок, которые принимают делегат вместо интерфейса, но:
Enumerable.OrderBy
Enumerable.Select
перед вызовом Enumerable. SequenceEqual
IEqualityComparer
в терминах Func