Самый крутой трюк с C# LINQ / Lambdas, который вы когда-либо использовали?

Видел сообщение о скрытых функциях в C#, но не многие люди написали пример linq / lambdas, поэтому ... интересно ...

What's the coolest (as in the most elegant) use of the C# LINQ and/or Lambdas/anonymous delegates you have ever saw/written?

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

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
42
0
13 583
14

Ответы 14

LINQ Raytracer, безусловно, возглавляет мой список =)

Я не совсем уверен, можно ли его назвать элегантным, но это определенно самое крутое linq-выражение, которое я когда-либо видел!

О, и просто чтобы быть предельно ясным; Я сделал это нет написал (Люк Хобан сделал)

Напоминает мне Madlebrot в SQL: thedailywtf.com/Articles/…

RHSeeger 18.08.2009 21:01

Я слышал подкаст с Люком, где он говорил, что использовал трассировщик лучей, чтобы «проверить» новый язык. Поэтому, когда появился LINQ, он просто применил к нему свой стандартный «тест», и родился LINQ Raytracer.

Cameron MacFarland 28.04.2010 08:52

Я пытался придумать крутой способ создания элемента управления навигацией для создаваемого мной веб-сайта. Я хотел использовать обычные неупорядоченные элементы списка HTML (с использованием стандартного CSS "Рыба-присоска" вид) с эффектом наведения мыши при верхней навигации, который открывает выпадающие элементы. У меня был зависящий от sql кешированный набор данных с двумя таблицами (NavigationTopLevels и NavigationBottomLevels). Затем все, что мне нужно было создать, это создать два объекта класса (TopNav и SubNav) с несколькими необходимыми свойствами (класс TopNav должен был иметь общий список элементов bottomnav -> ListПодэлементы).


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 в этом случае помогает сэкономить время.

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

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);
    }
}

Не принесите много пользы, если не знаете, как ими пользоваться. Чтобы знать это, вам нужно знать, для чего они:

Почему это все еще не стандартная функциональность .net?

user180326 15.02.2010 23:22

Похоже на метод расширения linq Zip ().

Larry 04.08.2014 16:19

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

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

Спас меня так много, если ... еще если ... еще если ... еще ЕСЛИ! заявления

ух ты! всегда впечатлен тем, что люди придумали с 555, возможно, мы слишком часто живем в типизированном мире.

chakrit 19.09.2008 00:21

Этот подход сейчас практически устарел, начиная с C# 7.

Dmitri Nesteruk 30.11.2019 13:53

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

Это то, что я называю элегантным!

Это точно :-) Я люблю это.

chakrit 19.09.2008 00:19

Заставляет меня задаться вопросом, почему нам пришлось так долго ждать появления такой технологии?

Attila Kun 11.04.2010 01:43

На самом деле, я очень горжусь этим для создания документов Excel: http://www.aaron-powell.com/linq-to-xml-to-excel

Ссылка больше не активна?

asgerhallas 27.04.2010 01:05

@asgerhallas - Я обновил ссылку на моем обновленном сайте.

Aaron Powell 28.04.2010 08:49

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

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.

Совсем недавно я сделал одну (немного сумасшедшую, но интересную) вещь вроде этой:

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

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

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

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

В противном случае Google для проекта Brahma, вы получите нужные страницы.

Чрезвычайно классная штука.

ГДж

На мой взгляд, двойственность между делегатами (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 );

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

Возможно, не самые крутые, но в последнее время я использую их каждый раз, когда у меня есть блок кода, который снова и снова загружает 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 для каждой команды, объекта и т. д.

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

https://github.com/wasabii/OLinq

Другие вопросы по теме