我们曾经尝试过的最酷的C#LINQ / Lambdas技巧?

时间:2020-03-05 18:43:29  来源:igfitidea点击:

在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?

如果它也已经投入生产,那就加分!

解决方案

回答

LINQ Raytracer当然是我的首选=)

我不太确定是否可以称得上优雅,但这无疑是我见过的最酷的linq表达式!

哦,而且要非常清楚。我没有写(卢班·霍班写了)

回答

我试图提出一种很酷的方法来为我正在构建的网站构建导航控件。我想使用常规的HTML无序列表元素(采用标准CSS" Sucker Fish"外观)以及顶部导航鼠标悬停效果来显示下拉项。我有一个具有两个表(NavigationTopLevels和NavigationBottomLevels)的依赖于SQL的缓存数据集。然后,我要做的就是创建两个具有少量必需属性的类对象(TopNav和SubNav)(TopNav类必须具有bottomnav项目的通用列表-> List <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可以节省时间。

回答

http://igoro.com/archive/extended-linq-additional-operators-for-linq-to-objects/

http://igoro.com/archive/7-tricks-to-simplify-your-programs-with-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);
    }
}

如果我们不知道如何使用它们,请不要做太多事情。为了知道这一点,我们需要知道它们的用途:

  • 什么是咖喱?
  • 什么是y组合器?

回答

长期运行的LINQ查询的进度报告。在博客文章中,我们可以找到一个扩展方法WithProgressReporting(),它使我们可以在执行linq查询时发现并报告其进度。

回答

不是我的设计,而是我使用了几次,这是一个类型开关声明:http://community.bartdesmet.net/blogs/bart/archive/2008/03/30/a-functional-c-type-switch .aspx

如果...否则,如果...否则,如果...否则,如果救了我那么多!陈述

回答

我认为LINQ是对.NET的重大更改,它是一个非常强大的工具。
我在生产中使用LINQ to XML,用两行代码将6MB XML文件(具有20多个节点级别)的记录解析和过滤到数据集中。
在LINQ之前,这将花费数百行代码和几天的时间进行调试。
那就是我所说的优雅!

回答

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

回答

使用属性:

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。在这个例子中,我选择使用letwhere子句。

回答

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

  • http://tomasp.net/blog/reactive-iv-reactivegame.aspx

回答

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

它可以用于使用" Linq to GPU"将并行计算卸载到GPU。我们在linq中编写一个"查询",然后梵天将其翻译为HLSL(高级着色器语言),以便DirectX可以在GPU上对其进行处理。

这个站点只会让我粘贴一个链接,因此请尝试从dotnetrocks进行以下网络广播:

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

在Google for Brahma Project中,我们将获得正确的页面。

非常酷的东西。

GJ

回答

对我来说,代表(Func &lt;T,R>Action &lt;T>)和表达式(Expression &lt;Func &lt;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 );

注意:几周前,我最初在网上看到了此内容,然后丢失了链接,此后到处都有大量变种出现,所以我担心不能给出适当的归因。

回答

也许不是最酷的方法,但是最近我在有一段代码反复使用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块一千五百万次。