2008-09-02 3 views
26

Я пишу несколько расширений для имитации карты и сокращения функций в Lisp.Общие карты/Сократить список расширений в C#

public delegate R ReduceFunction<T,R>(T t, R previous); 
public delegate void TransformFunction<T>(T t, params object[] args); 

public static R Reduce<T,R>(this List<T> list, ReduceFunction<T,R> r, R initial) 
{ 
    var aggregate = initial; 
    foreach(var t in list) 
     aggregate = r(t,aggregate); 

    return aggregate; 
} 
public static void Transform<T>(this List<T> list, TransformFunction<T> f, params object [] args) 
{ 
    foreach(var t in list) 
     f(t,args); 
} 

Преобразование функция позволит сократить хлама, как:

foreach(var t in list) 
    if(conditions && moreconditions) 
     //do work etc 

ли это смысл? Может быть, лучше?

+2

Это уже существует. Взгляните на C# 3/LINQ. – yfeldblum 2008-11-10 16:16:58

ответ

35

Они очень похожи на расширения в Linq уже:

//takes a function that matches the Func<T,R> delegate 
listInstance.Aggregate( 
    startingValue, 
    (x, y) => /* aggregate two subsequent values */); 

//takes a function that matches the Action<T> delegate 
listInstance.ForEach( 
    x => /* do something with x */); 

Почему второй пример называется Transform? Вы собираетесь каким-то образом изменить значения в списке? Если это так, вам может быть лучше использовать ConvertAll<T> или Select<T>.

2

Вместо этого я бы использовал встроенные делегаты Func. Этот же код будет работать с любым IEnumerable. Ваш код превратится в:

public static R Reduce<T,R>(this IEnumerable<T> list, Func<T,R> r, R initial) 
{ 
    var aggregate = initial; 
    foreach(var t in list) 
     aggregate = r(t,aggregate); 

    return aggregate; 
} 
public static void Transform<T>(this IEnumerable<T> list, Func<T> f) 
{ 
    foreach(var t in list) 
      f(t); 
} 
1

Вы можете добавить способ сделать карту, но возвращает новый список, вместо того чтобы работать в списке передается в (и возвращает список может оказаться полезным для цепи других операций) ... возможно, перегруженная версия с Логическое значение, указывающее, если вы хотите, чтобы вернуть новый список или нет, как таковой:

public static List<T> Transform<T>(this List<T> list, TransformFunction<T> f, 
     params object [] args) 
{ 
    return Transform(list, f, false, args); 
} 

public static List<T> Transform<T>(this List<T> list, TransformFunction<T> f, 
     bool create, params object [] args) 
{ 
    // Add code to create if create is true (sorry, 
    // too lazy to actually code this up) 
    foreach(var t in list) 
     f(t,args); 
    return list; 
} 
Смежные вопросы