2008-08-26 11 views
42

Sah einen Beitrag über versteckte Funktionen in C#, aber nicht viele Leute so Linq/lambdas Beispiel geschrieben haben ... Ich frage mich, ...Coolster C# LINQ/Lambdas Trick, den du je gezogen hast?

Was das coolste ist (wie in der eleganteste) Verwendung der C# LINQ und/oder Lambdas/anonyme Delegierte, die Sie jemals gesehen/geschrieben haben?

Bonus, wenn es auch in Produktion gegangen ist!

Antwort

27

Die LINQ Raytracer sicherlich Tops meine Liste =)

Ich bin mir nicht ganz sicher, ob gilt als elegant, aber es ist mit Sicherheit der coolste Linq-Ausdruck, den ich je gesehen habe!

Oh, und nur um extrem klar zu sein; Ich tat nicht schreibe es (Luke Hoban tat)

+1

Erinnert mich an die Madlebrot in SQL: http://thedailywtf.com/Articles/Stupid-Coding-Tricks-The-TSQL-Madlebrot.aspx – RHSeeger

+0

ich einen Podcast mit Luke gehört, wo er Er sagte, er benutzte einen Raytracer, um eine neue Sprache zu "testen". Als LINQ daher kam, verwendete er einfach seinen Standard-Test und der LINQ-Raytracer wurde geboren. –

1

Ich versuchte, mit einem coolen Weg zu kommen, um eine Navigationssteuerung für eine Website zu bauen, die ich baute. Ich wollte reguläre HTML-ungeordnete Listenelemente (unter Verwendung des Standards CSS "Sucker Fish" look) mit einem Top-Navigation-Mouseover-Effekt verwenden, der die Dropdown-Elemente aufdeckt. Ich hatte ein SQL-abhängiges zwischengespeichertes DataSet mit zwei Tabellen (NavigationTopLevels & NavigationBottomLevels). Dann musste ich nur noch zwei Klassenobjekte (TopNav & SubNav) mit den wenigen erforderlichen Eigenschaften erstellen (die TopNav-Klasse musste eine generische Liste der unterenNav-Elemente haben -> Liste <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();

Es ist vielleicht nicht die „coolste“ aber für eine Menge Leute, die dynamische Navigation haben wollen, sein süßen in der üblichen Schleifenlogik zu verwirren um nicht zu haben, die damit kommt. LINQ ist in diesem Fall eine Zeitersparnis.

20

Einige grundlegende Funktionalen:

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

nicht viel Gutes tun, wenn Sie nicht wissen, wie sie zu benutzen. Um das zu wissen, müssen Sie wissen, was sie für:

+3

Warum ist dies immer noch nicht .net Standardfunktionalität? –

+0

Sieht aus wie die Zip() linq-Erweiterungsmethode. – Larry

11

Progress Reporting für Abfragen mit langer Laufzeit LINQ. Im Blogpost finden Sie eine Erweiterungsmethode mit WithProgressReporting(), mit der Sie den Fortschritt einer linq-Abfrage bei ihrer Ausführung erkennen und melden können.

1

Ich denke, dass LINQ eine große Änderung an .NET ist und es ist ein sehr mächtiges Werkzeug.

Ich verwende LINQ to XML in der Produktion zu analysieren und Datensätze aus einer 6 MB XML-Datei (mit 20 + Knoten Ebenen) in ein Dataset in zwei Zeilen Code zu filtern.

Vor LINQ hätte dies Hunderte Zeilen Code und Tage zum Debuggen benötigt.

Das nenne ich elegant!

+0

Es ist sicher :-) Ich liebe es. – chakrit

+0

Wundert mich, warum wir so lange auf eine solche Technologie warten mussten? – kahoon

0

mit Attributen Arbeiten:

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

Die GetAttributes Erweiterungsmethode:

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 ist Produktionscode und definiert auch GetAttribute und HasAttribute. Ich entschied mich, die let und where Klauseln in diesem Beispiel zu verwenden.

16

Bei weitem der beeindruckendste Linq Umsetzung ich je bin gekommen, ist die Brahma Rahmen.

Es kann verwendet werden, um parallele Berechnungen zu der GPU mit 'Linq to GPU' zu entladen. Sie schreiben eine 'Query' in linq, und Brahma übersetzt sie dann in HLSL (High Level Shader Language), damit DirectX sie auf der GPU verarbeiten kann.

Diese Seite wird mir nur einen Link einfügen lassen, um diesen Webcast von dotnetrocks versuchen:

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

Else für Brahma Projekt Google, werden Sie die richtigen Seiten bekommen.

Extrem coole Sachen.

GJ

+0

+1: Holy cr @ p! Das ist großartig. Und böse. Sehr teuflisch. –

4

Für mich bin die Dualität zwischen Delegierten (Func<T,R>, Action<T>) und Ausdrücke (Expression<Func<T,R>>Expression<Action<T>>) ist das, was Anlass zu der klügstenen Verwendung von Lambda-Ausdrücke gibt.

Zum Beispiel:

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

Dann können Sie „sicher“ INotifyPropertyChanged implementieren durch

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

Hinweis Aufruf: ich dies vor auf den ersten wenigen Wochen auf dem Netz sah, verlor dann auf den Link und seither sind hier und da ein paar Variationen aufgetaucht, also kann ich leider keine korrekte Zuschreibung geben.

1

Vielleicht nicht die coolsten, aber in letzter Zeit habe ich sie immer benutzt Ich habe einen Block von Code, der C + Pd immer und immer wieder bekommt, nur um ein paar Zeilen zu ändern. Zum Beispiel Befehle einfache SQL-Lauf Daten abrufen kann wie so geschehen:

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

die eine Liste der Beiträge zurückkehren konnten, die heute erstellt wurden. Auf diese Weise muss ich den try-catch-finally-Block fünfzehn Millionen Mal für jeden Befehl, jedes Objekt und so weiter kopieren und einfügen.