views:

3018

answers:

14

Saw a post about hidden features in C# but not a lot of people have written linq/lambdas example so... I wonder...

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

Bonus if it has went into production too!

+16  A: 

The LINQ Raytracer certainly tops my list =)

I'm not quite sure if qualifies as elegant but it is most certainly the coolest linq-expression I've ever seen!

Oh, and just to be extremely clear; I did not write it (Luke Hoban did)

Markus Olsson
Reminds me of the Madlebrot in SQL: http://thedailywtf.com/Articles/Stupid-Coding-Tricks-The-TSQL-Madlebrot.aspx
RHSeeger
I heard a podcast with Luke, where he was saying he used writing a ray tracer to "test" out a new language. So when LINQ came along he simply applied his standard "test" to it, and the LINQ Raytracer was born.
Cameron MacFarland
+1  A: 

I was trying to come up with a cool way to build a navigation control for a website I was building. I wanted to use regular HTML unordered list elements (employing the standard CSS "Sucker Fish" look) with a top-navigation mouse-over effect that reveals the drop down items. I had a sql dependent cached DataSet with two tables (NavigationTopLevels & NavigationBottomLevels). Then all I had to was create two class objects (TopNav & SubNav) with the few required properties (the TopNav class had to have a generic list of bottomnav items -> 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();

It might not be the "coolest" but for a lot of people who want to have dynamic navigation, its sweet not to have to muddle around in the usual looping logic that comes with that. LINQ is, if anything a time saver in this case.

Ian Patrick Hughes
+13  A: 

Some basic functionals:

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

Don't do much good if you don't know how to use them. In order to know that, you need to know what they're for:

Chris Ammerman
Why is this still not .net standard functionality?
jdv
A: 

@Turbulent Intellect: how about explaining a little the usage of your "basic functionals"?

In order to know that, you need to understand what they're for, which is a long discussion. Added a couple relevant links.
Chris Ammerman
Please use comments for commenting.
bzlm
+8  A: 

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.

Samuel Jack
+2  A: 

Not my design but I've used it a few times, a typed-switch statement: http://community.bartdesmet.net/blogs/bart/archive/2008/03/30/a-functional-c-type-switch.aspx

Saved me so many if... else if... else if... else IF! statements

Slace
wow! always impressed with what ppl came up w/ it 555maybe we live in a typed world too much.
chakrit
+1  A: 

I think that LINQ is a major change to .NET and it is a very powerful tool.

I use LINQ to XML in production to parse and filter records from a 6MB XML file (with 20+ node levels) into a dataset in two lines of code.

Before LINQ this would have taken hundreds of lines of code and days to debug.

That's what I call elegant!

ThatBloke
It sure is :-) I'm lovin' it.
chakrit
Makes me wonder why we had to wait this long for a technology like this to arise?
kahoon
+1  A: 

Actually, I'm quite proud of this for generating Excel docments: http://www.aaron-powell.com/linq-to-xml-to-excel

Slace
The link isn't active any more?
asgerhallas
@asgerhallas - I've updated the link to where it is on my updated website
Slace
A: 

Working with attributes:

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

The GetAttributes extension method:

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 is production code and also defines GetAttribute and HasAttribute. I chose to use the let and where clauses in this example.

Bryan Watts
+2  A: 

Hi,

I did one (a bit crazy, but interesting) thing like that just recently:

Tomas Petricek
+9  A: 

Hi All,

By far the most impressive Linq implementation i've ever come across is the Brahma framework.

It can be used to offload parallel calculations to the GPU using 'Linq to GPU'. You write a 'query' in linq, and then Brahma translates it into HLSL (High Level Shader Language) so DirectX can process it on the GPU.

This site will only let me paste one link so try this webcast from dotnetrocks:

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

Else google for Brahma Project, you'll get the right pages.

Extremely cool stuff.

GJ

gjvdkamp
+1: Holy cr@p! Thats awesome. And evil. Very evil.
Cameron MacFarland
+1  A: 

To me, the duality between delegates (Func<T,R>, Action<T>) and expressions (Expression<Func<T,R>> Expression<Action<T>>) is what gives rise to the most clever uses of lambdas.

For example:

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

Then you can "safely" implement INotifyPropertyChanged by calling

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

Note : I saw this on the web at first a few weeks ago, then lost the link and a score of variations have cropped up here and there since then so I'm afraid I cannot give proper attribution.

Thomas Dufour
A: 

Perhaps not the coolest, but recently I have been using them anytime I have a block of code that gets C+Pd over and over again only to have a few lines change. For instance, running simple SQL commands to retrieve data can be done like so:

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

Which could return a list of Posts that were created today. This way I don't have to copy and paste the try-catch-finally block fifteen million times for each command, object, et cetera.

Krisc