2008-08-26 4 views
42

Видел пост о скрытых возможностях C#, но не много людей написали Linq/лямбды пример так ... Интересно ...Самый классный C# LINQ/Lambdas трюк, который вы когда-либо вытаскивали?

Что крутая (как в самом элегантном) использование C# LINQ и/или Lambdas/анонимные делегаты, которых вы когда-либо видели/писали?

Бонус, если он тоже вступил в производство!

ответ

27

LINQ Raytracer конечно же вершины мой список =)

Я не совсем уверен, что если квалифицируется как элегантный, но это, безусловно, самая крутая LINQ-выражение, которое я когда-либо видел!

О, и просто быть предельно ясным; Я сделал не написал (Luke Hoban сделал)

+1

Напоминает мне Madlebrot в SQL: http://thedailywtf.com/Articles/Stupid-Coding-Tricks-The-TSQL-Madlebrot.aspx – RHSeeger 2009-08-18 17:01:29

+0

Я слышал подкаста с Люком, где он говорил, что он использовал письмо лучей, чтобы «проверить» новый язык. Поэтому, когда LINQ пришел, он просто применил свой стандартный «тест» к нему, и появился LINQ Raytracer. – 2010-04-28 04:52:25

1

Я пытался придумать классный способ создания навигационного элемента управления для сайта, который я строил. Я хотел использовать регулярные неупорядоченные элементы списка HTML (с использованием стандарта CSS "Sucker Fish" look) с эффектом «мышь сверху», который показывает выпадающие элементы. У меня был sql-зависимый кешированный DataSet с двумя таблицами (NavigationTopLevels & NavigationBottomLevels). Тогда все, что мне нужно было создать два объекта класса (TopNav SubNav) с несколькими требуемыми свойствами (класс TopNav должен был иметь общий список нижних элементов -> Список <SubNav> SubItems).

 

var TopNavs = from n in ds.NavigationTopLevels select new TopNav { NavigateUrl = String.Format("{0}/{1}", tmpURL, n.id), Text = n.Text, id = n.id, SubItems = new List<SubNav>( from si in ds.NavigationBottomLevels where si.parentID == n.id select new SubNav { id = si.id, level = si.NavLevel, NavigateUrl = String.Format("{0}/{1}/{2}", tmpURL, n.id, si.id), parentID = si.parentID, Text = si.Text } ) }; List<TopNav> TopNavigation = TopNavs.ToList();

Это не может быть «крутой», но для многих людей, которые хотят иметь динамическую навигацию, ее сладкие не должны запутывать вокруг в обычной обхвата логики, которая приходит с этим. LINQ - это что-то в этом случае.

20

Некоторые основные функционалы:

public static class Functionals 
{ 
    // One-argument Y-Combinator. 
    public static Func<T, TResult> Y<T, TResult>(Func<Func<T, TResult>, Func<T, TResult>> F) 
    { 
     return t => F(Y(F))(t); 
    } 

    // Two-argument Y-Combinator. 
    public static Func<T1, T2, TResult> Y<T1, T2, TResult>(Func<Func<T1, T2, TResult>, Func<T1, T2, TResult>> F) 
    { 
     return (t1, t2) => F(Y(F))(t1, t2); 
    } 

    // Three-arugument Y-Combinator. 
    public static Func<T1, T2, T3, TResult> Y<T1, T2, T3, TResult>(Func<Func<T1, T2, T3, TResult>, Func<T1, T2, T3, TResult>> F) 
    { 
     return (t1, t2, t3) => F(Y(F))(t1, t2, t3); 
    } 

    // Four-arugument Y-Combinator. 
    public static Func<T1, T2, T3, T4, TResult> Y<T1, T2, T3, T4, TResult>(Func<Func<T1, T2, T3, T4, TResult>, Func<T1, T2, T3, T4, TResult>> F) 
    { 
     return (t1, t2, t3, t4) => F(Y(F))(t1, t2, t3, t4); 
    } 

    // Curry first argument 
    public static Func<T1, Func<T2, TResult>> Curry<T1, T2, TResult>(Func<T1, T2, TResult> F) 
    { 
     return t1 => t2 => F(t1, t2); 
    } 

    // Curry second argument. 
    public static Func<T2, Func<T1, TResult>> Curry2nd<T1, T2, TResult>(Func<T1, T2, TResult> F) 
    { 
     return t2 => t1 => F(t1, t2); 
    } 

    // Uncurry first argument. 
    public static Func<T1, T2, TResult> Uncurry<T1, T2, TResult>(Func<T1, Func<T2, TResult>> F) 
    { 
     return (t1, t2) => F(t1)(t2); 
    } 

    // Uncurry second argument. 
    public static Func<T1, T2, TResult> Uncurry2nd<T1, T2, TResult>(Func<T2, Func<T1, TResult>> F) 
    { 
     return (t1, t2) => F(t2)(t1); 
    } 
} 

Не делать очень хорошо, если вы не знаете, как использовать их. Для того, чтобы знать, что вы должны знать, что они для:

+3

Почему это еще не стандартная функциональность .net? – 2010-02-15 20:22:26

+0

Похож на метод расширения linq Zip(). – Larry 2014-08-04 12:19:10

11

Progress Reporting долго погонных LINQ запросов. В сообщении в блоге вы можете найти метод расширения WithProgressReporting(), который позволяет вам обнаруживать и сообщать о ходе выполнения запроса linq по мере его выполнения.

3

Не мой дизайн, но я использовал его несколько раз, в типизированных переключатель заявление: http://community.bartdesmet.net/blogs/bart/archive/2008/03/30/a-functional-c-type-switch.aspx

Сохраненный меня так много, если ... еще если ... иначе, если ... еще ЕСЛИ! операторы

+0

ничего себе! всегда впечатлен тем, что придумал ppl w/it 555 , может быть, мы слишком много живем в типизированном мире. – chakrit 2008-09-18 20:21:10

+1

lol. Конечно, всегда есть полиморфизм :-) – Stimul8d 2011-04-07 12:23:04

1

Я думаю, что LINQ является серьезным изменением для .NET, и это очень мощный инструмент.

Я использую LINQ to XML для создания и фильтрации записей из XML-файла размером 6 МБ (с 20 + уровнями узлов) в набор данных в двух строках кода.

Перед LINQ это потребовало бы сотен строк кода и дней для отладки.

Это то, что я называю шикарным!

0

Работа с атрибутами:

private void WriteMemberDescriptions(Type type) 
{ 
    var descriptions = 
     from member in type.GetMembers() 
     let attributes = member.GetAttributes<DescriptionAttribute>(true) 
     let attribute = attributes.FirstOrDefault() 
     where attribute != null 
     select new 
     { 
      Member = member.Name, 
      Text = attribute.Description 
     }; 

     foreach(var description in descriptions) 
     { 
      Console.WriteLine("{0}: {1}", description.Member, description.Text); 
     } 
} 

Метод GetAttributes расширение:

public static class AttributeSelection 
{ 
    public static IEnumerable<T> GetAttributes<T>(this ICustomAttributeProvider provider, bool inherit) where T : Attribute 
    { 
     if(provider == null) 
     { 
      throw new ArgumentNullException("provider"); 
     } 

     return provider.GetCustomAttributes(typeof(T), inherit).Cast<T>(); 
    } 
} 

AttributeSelection является производство код а также определяет GetAttribute и HasAttribute. В этом примере я решил использовать предложения let и where.

16

К наиболее впечатляющим реализация Linq я когда-либо сталкивался является Брахма фреймворк.

Его можно использовать для разгрузки параллельных вычислений на графический процессор с использованием «Linq to GPU». Вы пишете «запрос» в linq, а затем Brahma переводит его в HLSL (High Shader Language), поэтому DirectX может обрабатывать его на графическом процессоре.

Этот сайт позволит только мне вставить одну ссылку, чтобы попробовать эту веб-трансляцию из dotnetrocks:

http://www.dotnetrocks.com/default.aspx?showNum=466

Else Google для Брахмы проекта, вы получите правильные страницы.

Чрезвычайно классный материал.

GJ

4

Для меня, двойственность между делегатами (Func<T,R>, Action<T>) и выражениями (Expression<Func<T,R>>Expression<Action<T>>) является то, что приводит к самому умному использованию лямбды.

Например:

public static class PropertyChangedExtensions 
{ 
    public static void Raise(this PropertyChangedEventHandler handler, Expression<Func<object>> propertyExpression) 
    { 
     if (handler != null) 
     { 
      // Retrieve lambda body 
      var body = propertyExpression.Body as MemberExpression; 
      if (body == null) 
       throw new ArgumentException("'propertyExpression' should be a member expression"); 

      // Extract the right part (after "=>") 
      var vmExpression = body.Expression as ConstantExpression; 
      if (vmExpression == null) 
       throw new ArgumentException("'propertyExpression' body should be a constant expression"); 

      // Create a reference to the calling object to pass it as the sender 
      LambdaExpression vmlambda = Expression.Lambda(vmExpression); 
      Delegate vmFunc = vmlambda.Compile(); 
      object vm = vmFunc.DynamicInvoke(); 

      // Extract the name of the property to raise a change on 
      string propertyName = body.Member.Name; 
      var e = new PropertyChangedEventArgs(propertyName); 
      handler(vm, e); 
     } 
    } 
} 

Тогда можно «безопасно» осуществлять INotifyPropertyChanged по телефону

if (PropertyChanged != null) 
    PropertyChanged.Raise(() => MyProperty); 

Примечание: Я видел это в Интернете в первую несколько недель назад, а затем потерял связь и с тех пор меняются несколько вариаций, поэтому я боюсь, что не могу дать надлежащую атрибуцию.

1

Возможно, это не самый классный, но в последнее время я использую их в любое время, когда у меня есть блок кода, который снова и снова запускает C + Pd только для изменения нескольких строк. Например, запуск простой SQL команды для получения данных можно сделать так:

SqlDevice device = GetDevice(); 

return device.GetMultiple<Post>(
    "GetPosts", 
    (s) => { 
     s.Parameters.AddWithValue("@CreatedOn", DateTime.Today); 

     return true; 
    }, 
    (r, p) => { 
     p.Title = r.Get<string>("Title"); 

     // Fill out post object 

     return true; 
    } 
); 

Что может возвращать список сообщений, которые были созданы сегодня. Таким образом, мне не нужно копировать и вставлять блок try-catch-finally пятнадцать миллионов раз для каждой команды, объекта и т. Д.

0

OLINQ реактивные запросы LINQ по сравнению с INotifyingCollection - это позволяет делать (помимо прочего) агрегацию в реальном времени против больших наборов данных.

https://github.com/wasabii/OLinq