2009-01-29 14 views
8

Ich denke, ich verstehe das Konzept eines Delegaten in C# als Zeiger auf eine Methode, aber ich kann keine guten Beispiele finden, wo es eine gute Idee wäre, sie zu verwenden. Was sind Beispiele, die mit Delegierten entweder deutlich eleganter/besser sind oder mit anderen Methoden nicht gelöst werden können?C# - Kann mir jemand sagen, warum und wo ich Delegierte verwenden soll?

+0

Meine Güte, ich stellte diese Frage vor fast einem Jahr und jetzt ist es schwer vorzustellen, das Leben vor Delegierten/Lambda-Ausdrücke! Ich muss sagen, dass die Antworten hier noch einige der besten Beispiele im Netz sind. So ist die Macht von SO. – Alex

Antwort

6

Was genau meinst du mit Delegierten? Hier sind zwei Möglichkeiten, in denen sie verwendet werden können:

void Foo(Func<int, string> f) { 
//do stuff 
string s = f(42); 
// do more stuff 
} 

und

void Bar() { 
Func<int, string> f = delegate(i) { return i.ToString(); } 
//do stuff 
string s = f(42); 
// do more stuff 
} 

Der Punkt in der zweite ist, dass Sie neue Funktionen im laufenden Betrieb erklären können, als Delegierte. Dies kann weitgehend durch Lambda-Ausdrücke ersetzt werden und ist immer dann nützlich, wenn Sie eine kleine Logik haben, die Sie 1) an eine andere Funktion übergeben möchten oder 2) einfach wiederholt ausführen möchten. LINQ ist ein gutes Beispiel. Jede LINQ-Funktion verwendet einen Lambda-Ausdruck als Argument und gibt das Verhalten an. Wenn Sie beispielsweise List<int> l haben, ruft l.Select(x=>(x.ToString()) ToString() für jedes Element in der Liste auf. Und der Lambda-Ausdruck, den ich geschrieben habe, ist als Delegierter implementiert.

Der erste Fall zeigt, wie Select implementiert werden könnte. Sie nehmen einen Delegierten als Ihr Argument, und dann rufen Sie es bei Bedarf auf. Dadurch kann der Aufrufer das Verhalten der Funktion anpassen. Wenn Sie Select() erneut als Beispiel verwenden, garantiert die Funktion selbst, dass der Delegat, an den Sie übergeben werden, für jedes Element in der Liste aufgerufen wird, und die Ausgabe jedes Elements wird zurückgegeben. Was dieser Delegierte tatsächlich tut, ist Ihnen überlassen. Das macht es zu einer erstaunlich flexiblen und allgemeinen Funktion.

Natürlich werden sie auch für das Abonnieren von Veranstaltungen verwendet. Kurz gesagt, Delegaten ermöglichen Ihnen, Funktionen zu referenzieren, sie als Argument in Funktionsaufrufen zu verwenden, sie Variablen zuzuordnen und was Sie sonst noch tun möchten.

6

Ich verwende in erster Linie die für einfache asynch Programmierung. Eine Methode mit einer Delegates Begin ... -Methode zu starten, ist wirklich einfach, wenn Sie feuern und vergessen wollen.

Ein Delegat kann auch wie eine Schnittstelle verwendet werden, wenn Schnittstellen nicht verfügbar sind. Z.B. Aufruf Methoden von COM-Klassen, externe. NET-Klassen etc.

0

gibt es nicht wirklich etwas delgates wird lösen, dass nicht mit anderen Methoden gelöst werden kann, aber sie bieten eine elegantere Lösung.

Mit Delegaten kann jede Funktion verwendet werden, solange sie über die erforderlichen Parameter verfügt.

Die Alternative ist oft eine Art von speziell angefertigten Ereignissystem im Programm zu verwenden, zusätzliche Arbeit zu schaffen und mehr Bereiche für Bugs in

11

Die .NET 1.0 Delegierten zu kriechen:

this.myButton.Click += new EventHandler(this.MyMethod); 

Die .NET 2.0-Delegierte:

this.myOtherButton.Click += delegate { 
    var res = PerformSomeAction(); 
    if(res > 5) 
     PerformSomeOtherAction(); 
}; 

Sie scheinen ziemlich nützlich. Wie wäre es mit:

new Thread(new ThreadStart(delegate { 
    // do some worker-thread processing 
})).Start(); 
+0

Das ist einfach genial! Verstanden – SMUsamaShah

4

Ereignisse sind das offensichtlichste Beispiel. Vergleichen Sie, wie das Beobachtermuster in Java (Schnittstellen) und C# (Delegaten) implementiert ist.

Auch viele der neuen C# 3-Funktionen (zum Beispiel Lambda-Ausdrücke) basieren auf Delegaten und vereinfachen ihre Verwendung noch weiter.

3

Zum Beispiel in Multithread-Anwendungen. Wenn Sie möchten, dass mehrere Threads eine Kontrolle verwenden, sollten Sie Delegaten verwenden. Entschuldigung, der Code ist in VisualBasic.

Zuerst erklären Sie einen Delegaten

Private Delegate Sub ButtonInvoke(ByVal enabled As Boolean) 

Schreiben Sie eine Funktion/deaktivieren Taste aus

Private Sub enable_button(ByVal enabled As Boolean) 
    If Me.ButtonConnect.InvokeRequired Then 

     Dim del As New ButtonInvoke(AddressOf enable_button) 
     Me.ButtonConnect.Invoke(del, New Object() {enabled}) 
    Else 
     ButtonConnect.Enabled = enabled 
    End If 

End Sub 
2

ich mehrere Threads zu ermöglichen, nutzen sie die ganze Zeit mit LINQ, vor allem mit Lambda-Ausdrücke, zur Verfügung zu stellen eine Funktion zum Auswerten einer Bedingung oder zum Zurückgeben einer Auswahl. Verwenden Sie sie auch, um eine Funktion bereitzustellen, die zwei Elemente zum Sortieren vergleicht. Letzteres ist wichtig für generische Sammlungen, für die die Standardsortierung geeignet sein kann oder auch nicht.

var query = collection.Where(c => c.Kind == ChosenKind) 
         .Select(c => new { Name = c.Name, Value = c.Value }) 
         .OrderBy((a,b) => a.Name.CompareTo(b.Name)); 
2

Einer der Vorteile von Delegaten ist die asynchrone Ausführung.

Wenn Sie eine Methode asynchron aufrufen, wissen Sie nicht, wann sie ausgeführt wird. Sie müssen also einen Delegaten an diese Methode übergeben, der auf eine andere Methode verweist, die aufgerufen wird, wenn die erste Methode ausgeführt wurde. In der zweiten Methode können Sie Code schreiben, der Sie darüber informiert, dass die Ausführung abgeschlossen ist.

1

Einige andere Kommentare berührt auf der Asynchron-Welt ..., aber ich werde auf jeden Fall äußern, da mein Favorit ‚Geschmack‘ so zu tun, erwähnt wurde:

ThreadPool.QueueUserWorkItem(delegate 
{ 
    // This code will run on it's own thread! 
}); 

Auch ein großer Grund für die Delegierten für ist "Rückrufe". Lassen Sie uns sagen, dass ich ein wenig Funktionalität (asynchron), und Sie wollen, dass ich eine Methode nennen (sagen wir mal „AlertWhenDone“) ... Sie in einem „delegieren“, um Ihre Methode übergeben könnte wie folgt aussehen:

TimmysSpecialClass.DoSomethingCool(this.AlertWhenDone); 
1

Außerhalb ihrer Rolle in Ereignissen, die Sie wahrscheinlich kennen, wenn Sie WinForms oder asp.net verwendet haben, sind Delegaten nützlich, um Klassen flexibler zu machen (z. B. wie sie in LINQ verwendet werden).

Flexibilität zum "Finden" von Dingen ist ziemlich üblich. Sie haben eine Sammlung von Dingen, und Sie möchten eine Möglichkeit bieten, Dinge zu finden. Anstatt zu erraten, auf welche Weise jemand die Dinge finden könnte, können Sie dem Anrufer nun erlauben, den Algorithmus bereitzustellen, damit er Ihre Sammlung nach eigenem Ermessen durchsuchen kann.

Hier ist ein triviales Codebeispiel:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

namespace Delegates 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      Collection coll = new Collection(5); 
      coll[0] = "This"; 
      coll[1] = "is"; 
      coll[2] = "a"; 
      coll[3] = "test"; 

      var result = coll.Find(x => x == "is"); 

      Console.WriteLine(result); 

      result = coll.Find(x => x.StartsWith("te")); 

      Console.WriteLine(result); 

    } 

} 

public class Collection 
{ 
    string[] _Items; 

    public delegate bool FindDelegate(string FindParam); 

    public Collection(int Size) 
    { 
     _Items = new string[Size]; 

    } 

    public string this[int i] 
    { 
     get { return _Items[i]; } 
     set { _Items[i] = value; } 
    } 

    public string Find(FindDelegate findDelegate) 
    { 
     foreach (string s in _Items) 
     { 
      if (findDelegate(s)) 
       return s; 
     } 
     return null; 
    } 

} 
} 

Ausgabe

ist

Test

2

Technisch Delegierter ist ein Referenztyp verwendet eine Methode mit einer bestimmten Signatur zu kapseln und Typ

0

Gibt es ein Vorteil, das Rück einen Delegaten zu verwenden, wenn mit externen Anrufe an eine Datenbank zu tun?

Zum Beispiel kann ein Code:

static void Main(string[] args) { 

      DatabaseCode("test"); 

} 

public void DatabaseCode(string arg) { 

      .... code here ... 

} 

in Code B verbessert werden:

static void Main(string[] args) { 

      DatabaseCodeDelegate slave = DatabaseCode; 
      slave ("test"); 

} 

public void DatabaseCode(string arg) { 

      .... code here ... 

} 
public delegate void DatabaseCodeDelegate(string arg); 

Es scheint, dass dies subjektiv ist, sondern ein Gebiet, wo es starke widersprüchliche Aussichtspunkte?

Verwandte Themen