Coolest C# LINQ/Lambdas trick you've ever pulled?

后端 未结 14 1407
死守一世寂寞
死守一世寂寞 2020-12-22 17:00

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

相关标签:
14条回答
  • 2020-12-22 17:51

    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.

    0 讨论(0)
  • 2020-12-22 17:52

    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.

    0 讨论(0)
  • 2020-12-22 18:02

    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:

    • What is currying?
    • What is a y-combinator?
    0 讨论(0)
  • 2020-12-22 18:03

    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)

    0 讨论(0)
  • 2020-12-22 18:03

    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.

    0 讨论(0)
  • 2020-12-22 18:04

    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.

    0 讨论(0)
提交回复
热议问题