Announcement

Collapse
No announcement yet.

Frage zu Delegates

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Frage zu Delegates

    Hallo,

    folgender Programmcode welcher fehlerfrei compiliert und läuft:
    Code:
    using System;
    using System.Threading;
    
    namespace ConAppTimer
    {
    	/// <summary>
    	/// Summary description for Class1.
    	/// </summary>
    	
    	class TimerStatus
    	{
        public int vZaehler;
    		public Timer tmr;
    	}
    
    
    	class Ablauf
    	{
    		
    		[STAThread]
    		static void Main()
    		{
    			//Eine Instanz der Klasse Timerstatus wird erzeugt
    			TimerStatus tStatus = new TimerStatus();
    			//der Variable tDelegate vom Typ TimerCallback wird erzeugt
    			TimerCallback tDelegat = new TimerCallback(Ausfuehren); 
    			tStatus.tmr = new Timer(tDelegat, tStatus, 1000, 1000);
    			Console.ReadLine();
    		}
    
    		static void Ausfuehren(object Status)
    		{
          TimerStatus tStatus = (TimerStatus)Status;
    			tStatus.vZaehler ++;
    			Console.WriteLine("{0} : Methode zum {1}. Mal ausgeführt.", DateTime.Now,tStatus.vZaehler);
    			if (tStatus.vZaehler == 5)
    			{
           tStatus.tmr.Change(1000,2000);
    			 Console.WriteLine("Nun ein längeres Zeitintervall:");
    			}
    
    			if (tStatus.vZaehler == 10)
    			{
    				tStatus.tmr.Dispose();
    				tStatus.tmr = null;
    			}
    
     
    		}
    
    	}
    }
    warum wird in der fettgedruckten Zeile, die Methode "Ausführen" ohne Parameter aufgerufen?
    Herzliche Grüße

    Markus Lemcke
    barrierefreies Webdesign

  • #2
    Ausfuehren wird da nicht aufgerufen, sondern die Adresse von Ausfuehren an tDelegat übergeben.
    Günther

    Comment


    • #3
      Hallo Günther,

      woran sieht man das?
      Herzliche Grüße

      Markus Lemcke
      barrierefreies Webdesign

      Comment


      • #4
        Hallo Markus,

        ...woran sieht man das?
        das TimerCallback-Beispiel ist am Anfang weniger geeignet, weil die beteiligten Zutaten in den Klassen des .NET Frameworks "versteckt" sind. Wenn Du in Visual Studio 2005 das Wort TimerCallback mit der rechten Maustaste anklickst, kannst Du zur Definition im Namespace System.Threading springen. Dort zeigt Visual Studio die folgende Zeile an, wobei der Delegate-Prototyp sichtbar wird:

        public delegate void TimerCallback(object state);


        Das folgende Beispiel ist zum Verständniss der Zusammenhänge besser (weil kompakter):

        Code:
        using System;
        
        namespace SimpleDemo
        {
        	public class ClassSimpleDelegate
        	{	
        		public ClassSimpleDelegate()
        		{
        		}
        
        		public void DoWork(string sMsg)
        		{
        			System.Diagnostics.Trace.WriteLine(sMsg);   
        		}
        	}
        }
        Delegates treffen Festlegungen zwischen einer aufrufenden Komponente und einer aufgerufenen Komponente und sind somit im Bezug auf diese Aufgabe einem Interface ähnlich. Während ein Interface in der Regel gleich mehrere Interface-Methoden als geschlossenen Vertrag zwischen beiden beteiligten Stellen beschreibt, bezieht sich ein Delegate immer nur auf eine einzige Methode. Ein Delegate besteht aus 2 Teilen:

        1. Prototyp der Funktion
        2. Implementierung der Funktion

        Der Prototyp wird über das Schlüsselwort delegate deklariert und beschreibt die Methodensignatur (Rückgabewert und Parameter). Solange die Signatur passt, kann später jede beliebige Methode über den Prototypen aktiviert werden (d.h. Du darfst beim new-Aufruf jede Methode übergeben, die den gleichen Rückgabewert sowie die gleiche Parameter-Signatur verwendet):

        Code:
        delegate void DoWorkHandler(string sMsg);
        
        private void button1_Click(object sender, System.EventArgs e)
        {
        	ClassSimpleDelegate aObj = new ClassSimpleDelegate("Test");
        	aObj.DoWork("Das ist der direkte Weg");
        	DoWorkHandler aHdl = new DoWorkHandler(aObj.DoWork);
        	aHdl("Das ist ein Test für die Delegate-Methode");
        }
        Zuletzt editiert von Andreas Kosch; 05.02.2007, 13:49.

        Comment


        • #5
          Besser hätte ich das niemals erklären können.

          Woher man sowas weiß? Die Zeile TimerCallback tDelegat = new TimerCallback(Ausfuehren); initialisiert einen Timer. Für so einen Timer brauchst Du halt eine Stelle im Programm, wo Dein spezieller Code steht. Also muß eine Adresse übergeben werden. Außerdem deutet die Namensgebung "CallBack" darauf hin.
          Günther

          Comment


          • #6
            Hallo,

            Also, dass ich ein Delegate brauche wenn ich einer Klasse ein Ereignis hinzufügen möchte habe ich kapiert.
            Aber warum und was das deletate macht ist mir nicht wirklich klar!

            Vielleicht kann ein Delpianer, am besten anhand eines kommentierten codebeispiels mir die sache nochmal erklären!
            es hat bei mir im Hirn einfach noch nicht klick gemacht!
            Herzliche Grüße

            Markus Lemcke
            barrierefreies Webdesign

            Comment


            • #7
              Hallo Markus,

              Also, dass ich ein Delegate brauche wenn ich einer Klasse ein Ereignis hinzufügen möchte habe ich kapiert. Aber warum ..
              der Unterschied zwischen Delphi und .NET besteht darin, dass in .NET ein Event (Ereignis) in Wirklichkeit ein Multicast Delegate ist, dem mehrere Ereignisbehandlungsmethoden gleichzeitig zugeordnet werden können. Delphi ist ein vielen Stellen einfach nur deshalb einfacher, weil Borland einge Grenzen gesetzt hat. Im Gegensatz dazu ist .NET viel flexibler, was aber im Umkehrschluss auch dazu führt, dass es an den betreffenden Stellen kompilizierter als in Delphi zugeht.

              Microsoft hat allerdings bei den Events im .NET Framework 2.0 reagiert, indem gleich 2 Vereinfachungen hinzugefügt wurden:

              1. Action< T >

              Code:
              public event Action< string > OnIDEChanged; 
              
              ...
              
              OSDeveloperClassActionEvent aObj = new OSDeveloperClassActionEvent();
              aObj.OnIDEChanged += new Action<string>(aObj_OnIDEChanged);
              aObj.IDE = "Eigenschaftszuweisung löst das Event aus";
              2. Kombination delegate + Anonymous methods

              Code:
              OSDeveloperClassActionEvent aObj = new OSDeveloperClassActionEvent();
              aObj.OnIDEChanged += delegate(string obj)
                     {
                         MessageBox.Show(obj);
                      };
              aObj.IDE = "Eigenschaftszuweisung löst das Event aus";

              Comment

              Working...
              X