Entwickler-Ecke

C# - Die Sprache - Delegat


relapse - Fr 09.12.11 14:34
Titel: Delegat
Hallo, ich habe zwei Fragen: Wie kann ich einen Delegaten (ein Verweis auf Methode der Klasse A) von der Klasse A aus einer anderen KLasse B übergeben (Im Qellcode ist die Übergabe mit ??? markiert)? Wie soll der Delegat in der Klasse B deklariert werden (Deklaration mit !!! markiert)? Klasse B kennt Klasse A nicht.

C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
public class A {

  public delegate void MaskeSchliessen();

  public A(Ib b){
    MaskeSchliessen maskeSchliessen;
    maskeSchliessen = new MaskeSchliessen(AnwendungSchliessen);
    Objekt objekt = new Objekt();
    b.ObjektSpeichern(objekt, ???);
  }

  public static void AnwendungSchliessen() {
    Application.Current.Shutdown();
  }

}

public interface Ib {
  void ObjektSpeichern(Objekt objekt, !!!);  // man kann ja in einem Interface keine Delegaten deklarieren!
}

public class B : Ib {
  public void ObjektSpeichern(Objekt objekt, !!!) {}
}


Moderiert von user profile iconTh69: C#-Tags hinzugefügt


mats74 - Fr 09.12.11 15:06

Hallo relapse

Wenn ich dich richtig verstanden habe, sollte dieser Code funktionieren:

C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
    public class A
    {
        public delegate void MaskeSchliessen(); 

        public A(B b)
        { 
            MaskeSchliessen maskeSchliessen; 
            maskeSchliessen = new MaskeSchliessen(AnwendungSchliessen);
            Object objekt = new Object();
            b.ObjektSpeichern(objekt, maskeSchliessen);
        } 

        public static void AnwendungSchliessen()
        { 
            Application.Current.Shutdown(); 
        } 
    }

    public interface Ib
    { 
        public void ObjektSpeichern(Object objekt, Delegate verweis);
    } 

    public class B :Ib
    { 
        public void ObjektSpeichern(Object objekt, Delegate verweis)
        {
        } 
    }


EDIT: Sorry, mein Code hat noch einen Fehler.
In einer Schnittstelle kannst Du keinen public-Modifizierer setzen.

... ah, da warst Du schon schneller als ich. ok. :wink:


relapse - Fr 09.12.11 15:23

Danke!!! Ich habe bis jetzt delegates nur innerhalb einer einzelnen Klasse verwendet und nicht klassenübergreifend.

Hab's direkt ausprobiert - es läuft: Der Aufruf des Delegaten erfolgt dann so:

C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
    public class B :Ib
    { 
        public void ObjektSpeichern(Object objekt, Delegate verweis)
        {
          verweis.DynamicInvoke();
        } 
    }


Moderiert von user profile iconTh69: C#-Tags hinzugefügt


Th69 - Fr 09.12.11 16:22

Hallo relapse :welcome:

zu
Zitat:

// man kann ja in einem Interface keine Delegaten deklarieren!


Aber außerhalb, d.h. im Namensbereich

C#-Quelltext
1:
2:
3:
4:
5:
6:
public delegate void SaveDelegate();

public interface Ib

    void ObjektSpeichern(Object objekt, SaveDelegate verweis);
}


P.S: Ab C# 2.0 (bzw. 3.0) solltest du Action<> bzw. Func<> (bzw. die nicht-generischen Varianten ohne Parameter) als Delegates benutzen:

C#-Quelltext
1:
2:
3:
4:
public interface Ib

    void ObjektSpeichern(Object objekt, Action verweis);
}


mats74 - Fr 09.12.11 16:33

Hallo Th69

user profile iconTh69 hat folgendes geschrieben Zum zitierten Posting springen:
Aber außerhalb, d.h. im Namensbereich


Das habe ich leider übersehen.
Jetzt funktioniert der Code auch einwandfrei.

C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
    public delegate void MaskeSchliessen();

    public class A
    {
        public A(B b)
        {
            MaskeSchliessen maskeSchliessen;
            maskeSchliessen = new MaskeSchliessen(AnwendungSchliessen);
            Object objekt = new Object();
            b.ObjektSpeichern(objekt, maskeSchliessen);
        }

        public static void AnwendungSchliessen()
        {
            Application.Exit();
        }
    }

    public interface Ib
    {
        void ObjektSpeichern(Object objekt, Delegate verweis);
    }

    public class B : Ib
    {
        public void ObjektSpeichern(Object objekt, Delegate verweis)
        {
        }
    }

Wieder einmal was dazugelernt. :wink:


Th69 - Fr 09.12.11 17:09

Hallo mats74,

auch dein Delegat-Aufruf ist sehr umständlich. Es reicht einfach:

C#-Quelltext
1:
2:
Object objekt = new Object();
b.ObjektSpeichern(objekt, AnwendungSchliessen);


ujr - Mo 12.12.11 12:56

Hallo,

warum deklarierst Du den Delegaten, wenn Du ihn gar nicht benutzt? Richtig wäre doch:

user profile iconmats74 hat folgendes geschrieben Zum zitierten Posting springen:


C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
    public delegate void MaskeSchliessen();

    public interface Ib
    {
        void ObjektSpeichern(Object objekt, MaskeSchliessen verweis);
    }

    public class B : Ib
    {
        public void ObjektSpeichern(Object objekt, MaskeSchliessen verweis)
        {
           verweis();
        }
    }



Dann sparst Du auch das DynamicInvoke.


mats74 - Mo 12.12.11 17:44

Hallo ujr

user profile iconujr hat folgendes geschrieben Zum zitierten Posting springen:
Hallo,
warum deklarierst Du den Delegaten, wenn Du ihn gar nicht benutzt? ... Dann sparst Du auch das DynamicInvoke.

Da gebe ich Dir absolut recht.
So auf die Schnelle habe ich das Beispiel ganz einfach nicht korrekt zu Ende geschrieben.
Danke Dir für deine Berichtigung.