Laden...

Delegaten, wie genau?

Erstellt von math55 vor 14 Jahren Letzter Beitrag vor 14 Jahren 1.649 Views
math55 Themenstarter:in
314 Beiträge seit 2007
vor 14 Jahren
Delegaten, wie genau?

Hallo, ich verstehe das Konzept der delegates nicht richtig. Was kann man damit tun, was man ohne delegates nicht machen könnte?

Danke 😃

4.207 Beiträge seit 2003
vor 14 Jahren

Hallo,

Delegaten sind quasi normale Variablen, nur dass darin halt Code und keine Daten gespeichert werden. Was man damit machen kann, ist zum Beispiel, eine Funktion als Parameter zu übergeben.

Sprich, Du hast eine Funktion, die irgendwas langlaufendes macht, und idealerweise soll die Dir Bescheid sagen, wenn sie fertig ist, indem sie ihrerseits wieder eine Funktion bei Dir aufruft.

Nun möchtest Du das ganze aber nicht hart verdrahten, weil diese langlaufende Funktion allgemein nutzbar sein soll. Was also tun?

Ganz einfach: Die Rückrufmethode wird als Parameter mitgegeben (und weil das ja keine Daten sind, sondern Code, muss es eben ein Delegate sein).

Das war's eigentlich auch schon 😉

Viele Grüße,

Golo

PS: Als Besonderheit sei noch erwähnt, dass man in einem Delegate (also quasi in einer Variablen) mehrere Funktionen speichern kann. Es entspricht also eher einem Array aus Funktionen, als einer einfachen Variable.

Wissensvermittler und Technologieberater
für .NET, Codequalität und agile Methoden

www.goloroden.de
www.des-eisbaeren-blog.de

math55 Themenstarter:in
314 Beiträge seit 2007
vor 14 Jahren

Nun möchtest Du das ganze aber nicht hart verdrahten, weil diese langlaufende Funktion allgemein nutzbar sein soll. Was also tun?

Aha, was heisst denn jetzt aber hart verdrahten? Ich muss doch die Aufrufe so oder so im Code stehen haben. Kannst Du mal ein Beispiel hartverdrahtet und eins mit nem delegate posten?

Danke!!

49.485 Beiträge seit 2005
vor 14 Jahren

Hallo math55,

wie man was hart verdrahtet, weiß doch. Man ruft einfach die Methode direkt auf.

List<T>.FindAll ist ein Beispiel wo ein Delegat übergeben wird, nämlich die Funktion, die angibt, welche Elemente gefunden werden sollen. Codebeispiel in der :rtfm: Doku.

herbivore

math55 Themenstarter:in
314 Beiträge seit 2007
vor 14 Jahren

Hallo, verstehe...aber warum kann ich denn nicht direkt aufrufen? Mal das Codebeispiel aus MSDN:



   List<string> sublist = dinosaurs.FindAll(EndsWithSaurus);
 
    private static bool EndsWithSaurus(String s)
    {
        if ((s.Length > 5) && 
            (s.Substring(s.Length - 6).ToLower() == "saurus"))
        {
            return true;
        }
        else
        {
            return false;
        }
    }

Ich muss doch ohnehin angeben, welche Methode (welcher Code) genutzt werden soll. Oder geht es darum, dass es auch auf N andere Methoden passen würde?

Danke 😃

Grüße

2.760 Beiträge seit 2006
vor 14 Jahren

Ich muss doch ohnehin angeben, welche Methode (welcher Code) genutzt werden soll.

In diser Schreibweise baut der compiler den delegate.
Du könntest es aber auch folgendermaßen schreiben:


   public partial class Form1 : Form
   {
      public Form1()
      {
         InitializeComponent();
         List<string> dinosaurs = new List<string>();

         // Normaler delegate
         Predicate<string> myDelegate = new Predicate<string>(EndsWithSaurus);
         List<string> sublist = dinosaurs.FindAll(myDelegate);

         // Anonymer delegat
         Predicate<string> anonymerDelegate = delegate(string str)
         {
            return str.EndsWith("saurus");
         };
         sublist = dinosaurs.FindAll(anonymerDelegate);

         // Lambda expressions (andere Schreibweise für anonyme delegaten)
         sublist = dinosaurs.FindAll((str) => str.EndsWith("saurus"));
         // oder:
         sublist = dinosaurs.FindAll((str) => EndsWithSaurus(str));
      }

      private static bool EndsWithSaurus(String s)
      {
         return s.EndsWith("saurus");
      }
   }

Schau dir das mal an: [Artikel] Delegaten, anonyme Methoden, Lambda-Ausdrücke & Co.

[EDIT]

Oder geht es darum, dass es auch auf N andere Methoden passen würde?

Ja, einen Delegaten kannst du dir ähnlich wie ein Interface vorstellen nur das dieser halt mit methoden arbeitet.

49.485 Beiträge seit 2005
vor 14 Jahren

Hallo math55

Ich muss doch ohnehin angeben, welche Methode (welcher Code) genutzt werden soll. Oder geht es darum, dass es auch auf N andere Methoden passen würde?

es geht darum, dass die Methode List<T>.FindAll so geschrieben ist, dass sie einen Delegaten als Parameter bekommt und damit mit beliebigen Methoden (passender Signatur) aufgerufen werden kann. Darin liegt die Flexibilität und die Dynamik.

herbivore

math55 Themenstarter:in
314 Beiträge seit 2007
vor 14 Jahren

Hallo, habs jetzt geschnallt, vielen Dank!!

4.207 Beiträge seit 2003
vor 14 Jahren

Zumindest bei mir war es damals so, dass ich dann auch Events besser verstanden habe.

Und, falls Dich technische Details und Best Practices interessieren, guck mal hier: MSDN Webcast: Events und Delegates im Detail - Feinheiten in MSIL

Wissensvermittler und Technologieberater
für .NET, Codequalität und agile Methoden

www.goloroden.de
www.des-eisbaeren-blog.de

A
50 Beiträge seit 2009
vor 14 Jahren

hallo zusammen,

ich komme aus der c-welt, genauer gesagt aus der embedded welt und bin im moment damit beschäfftigt mich langsam aber sicher in .net einzuarbeiten.

das ganze mit delegate kann man mit einer callback funktion vergleichen, sehe ich das richtig? ein event stellt dann also einen interrupt da oder?
wenn beides "ja", dann hab ich verstanden, wenn nein, muss ich nochmal nachlesen 😉

gruß,
ai.se

B
5 Beiträge seit 2009
vor 14 Jahren

Eine Delegate kann man vergleichen mit einem Pointer auf eine Funktion. Ja ein Callback, ist ja auch nur ein Pointer zu einer Funktion, der übergeben wird.

Was ich persönlich ein sehr spannendes Thema finde, ist, dass man mit Delegaten in C# "die Möglichkeit" bekommt, Inline Asm zu benutzen. Leider lange nicht so effektiv und so sinnvoll, wie das in C++ möglich ist, aber für viele Dinge, gerade, wenn man viel mit Win32Apis und mit Speicherzugriffen arbeiten, sehr interessant.

Ein kleines Beispiel, wie man mit einer Delegaten Assembler Opcodes aus dem eigenen Prozess aufrufen kann:



using System;
using System.Reflection;

class Program
{
    public delegate uint Ret1ArgDelegate(uint arg1);
    static uint PlaceHolder1(uint arg1) { return 0; }
    
    public static byte[] asmBytes = new byte[]
        {        
0x89,0xD0, // MOV EAX,EDX
0xD1,0xC8, // ROR EAX,1
0xC3       // RET
        };
        
    unsafe static void Main(string[] args)
    {
        fixed(byte* startAddress = &asmBytes[0]) // Take the address of our x86 code
        {
            // Get the FieldInfo for "_methodPtr"
            Type delType = typeof(Delegate);
            FieldInfo _methodPtr = delType.GetField("_methodPtr", BindingFlags.NonPublic | BindingFlags.Instance);

            // Set our delegate to our x86 code
            Ret1ArgDelegate del = new Ret1ArgDelegate(PlaceHolder1);
            _methodPtr.SetValue(del, (IntPtr)startAddress);

            // Enjoy
            uint n = (uint)0xFFFFFFFC;
            n = del(n);
            Console.WriteLine("{0:x}", n);
        }
    }
}


Quelle

MfG

2.760 Beiträge seit 2006
vor 14 Jahren

(Coole Sache, das war mir so noch nicht bewusst. zu meiner Verteidigung muss ich allerdings sagen das ich in C#-Programmen Assembler noch nie vermisst habe 😉

49.485 Beiträge seit 2005
vor 14 Jahren

Hallo ai.se,

das ganze mit delegate kann man mit einer callback funktion vergleichen, sehe ich das richtig?

abgesehen davon, dass es hier um Methoden geht und man für den Aufruf einer nicht-statische Methode ein Objekt braucht, das deshalb zusätzlich zu dem Zeiger auf die Methode im Delegat enthalten ist, ja.

ein event stellt dann also einen interrupt da oder?

Ein Event ist erstmal nur ein Delegat, auf den von außerhalb der Klasse nur mit += und -= zugegriffen werden kann.

herbivore

A
50 Beiträge seit 2009
vor 14 Jahren

hallo zusammen,

dann liege ich ja garnicht so falsch^^
vielen dank für die kommentare!

gruß,
ai.se