43

看到一篇关于 C# 中隐藏功能的帖子,但没有很多人写过 linq/lambdas 示例,所以......我想知道......

你见过/写过的 C# LINQ 和/或 Lambdas/匿名委托的最酷(最优雅的)用法是什么?

如果它也已投入生产,将获得奖励!

4

14 回答 14

27

LINQ Raytracer无疑是我的首选=)

我不太确定是否符合优雅的条件,但它肯定是我见过的最酷的 linq 表达式!

哦,而且要非常清楚;我没有卢克霍班写的)

于 2008-08-26T19:04:51.973 回答
19

一些基本功能:

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

如果您不知道如何使用它们,那就不要做太多好事。为了知道这一点,您需要知道它们的用途:

于 2008-08-26T19:54:42.850 回答
18

到目前为止,我遇到过的最令人印象深刻的 Linq 实现是 Brahma 框架。

它可用于使用“Linq to GPU”将并行计算卸载到 GPU。您在 linq 中编写“查询”,然后 Brahma 将其转换为 HLSL(高级着色器语言),以便 DirectX 可以在 GPU 上处理它。

这个网站只允许我粘贴一个链接,所以试试这个来自 dotnetrocks 的网络广播:

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

其他谷歌搜索 Brahma Project,你会得到正确的页面。

非常酷的东西。

GJ

于 2009-08-18T15:32:35.360 回答
11

Progress Reporting for long running LINQ queries. In the blog post you can find an extension method WithProgressReporting() that lets you discover and report the progress of a linq query as it executes.

于 2008-09-17T09:02:33.407 回答
4

对我来说,委托 ( Func<T,R>, Action<T>) 和表达式 ( Expression<Func<T,R>> Expression<Action<T>>) 之间的对偶性导致了 lambda 最聪明的用法。

例如:

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

注意:几周前我最初在网上看到了这个,然后失去了链接,从那时起这里和那里出现了许多变体,所以我担心我无法给出正确的归属。

于 2009-08-18T21:28:56.127 回答
3

实际上,我为生成 Excel 文档感到非常自豪:http ://www.aaron-powell.com/linq-to-xml-to-excel

于 2008-09-17T09:36:03.047 回答
2

我最近做了一件(有点疯狂,但很有趣)的事情:

于 2008-11-28T00:47:17.553 回答
2

不是我的设计,但我已经用过几次了,一个 typed-switch 语句:http: //community.bartdesmet.net/blogs/bart/archive/2008/03/30/a-functional-c-type-switch .aspx

如果... else if... else if... else if 救了我这么多!陈述

于 2008-09-17T09:08:10.443 回答
1

我试图想出一种很酷的方法来为我正在构建的网站构建导航控件。我想使用常规的 HTML 无序列表元素(使用标准的CSS“Sucker Fish”外观)和顶部导航鼠标悬停效果,显示下拉项目。我有一个带有两个表(NavigationTopLevels 和 NavigationBottomLevels)的 sql 依赖缓存数据集。然后我所要做的就是创建两个类对象(TopNav 和 SubNav),它们具有几个必需的属性(TopNav 类必须有一个底部导航项的通用列表 -> List<SubNav> SubItems)。


var TopNavs = 来自 ds.NavigationTopLevels 中的 n 选择新的 TopNav { NavigateUrl = String.Format("{0}/{1}", tmpURL, n.id), 文本 = n.文本, id = n.id, 子项 = 新列表<子导航>( 来自 ds.NavigationBottomLevels 中的 si 其中 si.parentID == n.id 选择新的子导航 { id = si.id, 级别 = si.NavLevel, NavigateUrl = String.Format("{0}/{1}/{2}", tmpURL, n.id, si.id), parentID = si.parentID, 文本 = si.Text } ) }; 列表<TopNav> TopNavigation = TopNavs.ToList();

它可能不是“最酷的”,但对于许多想要动态导航的人来说,不必在随之而来的通常循环逻辑中混日子是很甜蜜的。在这种情况下,LINQ 可以节省时间。

于 2008-08-26T19:16:43.800 回答
1

我认为 LINQ 是对 .NET 的重大改变,它是一个非常强大的工具。

我在生产中使用 LINQ to XML 以两行代码将 6MB XML 文件(具有 20 多个节点级别)中的记录解析和过滤到数据集中。

在 LINQ 之前,这将需要数百行代码和数天的时间来调试。

这就是我所说的优雅!

于 2008-09-17T09:14:52.503 回答
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 块一千五百万次。

于 2010-04-28T13:00:10.923 回答
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是生产代码,还定义GetAttributeHasAttribute。在本例中,我选择使用letandwhere子句。

于 2008-11-22T20:41:18.397 回答
0

OLINQ 对 INotifyingCollection 的反应式 LINQ 查询 - 这些允许您(除其他外)对大型数据集进行实时聚合。

https://github.com/wasabii/OLinq

于 2013-08-28T11:05:00.677 回答