Announcement

Collapse
No announcement yet.

Funktionsaufrufe aus Basisklasse ...

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

  • Funktionsaufrufe aus Basisklasse ...

    Guten Morgen,
    ich habe ein kleines Problem bzw. ein Frage:

    folgende Voraussetzungen sind gegeben: ich habe eine Basisklasse Base_BL und eine abgeleitete Klasse Tasks_BL.
    In der Basisklasse ist eine Funktion "SetNewRecord" definiert, die per Reflektion eine Funktion der abgeleiteten Klasse aufrufen soll.
    Der Name der Funktion ist variable und wird bspw. per Parameter übergeben.

    So weit, so gut. Wenn diese Funktion einmalig vorhanden ist funktioniert das Ermitteln der Funktion per
    me.GetType.GetMethod("MethodenName")
    einwandfrei.

    Gibt es allerdings eine Überladung kann die Funktion nicht mehr eindeutig zugewiesen werden und der Aufruf knallt.
    Versuche ich noch ein Array mit den Parametertypen, liefert die Methode mir Nothing zurück:
    me.GetType.GetMethod("MethodenName", Reflection.BindingFlags.ExactBinding, NOTHING, arrParmTypes, NOTHING)

    Hat jemand eine Ahnung, wieso? Stimmt was an den BindingFlags nicht?
    Hüüüülfe!


    mfg
    CM

  • #2
    Hallo C.Mark,

    ich behaupte, da stimmt etwas mit Deinem Softwaredesign nicht. Dass eine Basisklasse eine Kindklasse per Reflection aufrufen muss, habe ich in meinem objektorientierten Leben noch nicht gesehen.

    Vielleicht hilft Dir die Basisklasse mit "MustInherit" zu bezeichnen, und dementsprechende Methodenrümpfe (abstrakte Methoden) mit "Public MustOverride Sub MeineAbstrakteMethode()" ohne jeglichen Methodenrumpf zu definieren?

    Die Abstrakten Methoden lassen sich aus den implementierten (nicht abstrakten) Methode der Basisklasse trotzdem aufrufen, da die Kinder diese implementieren müssen, und somit sichergestellt ist, dass ausführbarer Code vorhanden ist.

    Beschreibe doch mal, warum Du das Ganze über Reflection lösen musst/möchtest, und was die Kriterien sind, welche Methode aufgerufen werden soll (Dynamic invoke?) ?

    Viele Grüße
    _ntr_

    Comment


    • #3
      Hallo,

      Hintergrund ist der, dass der Name der durch die Basisklasse aufzurufenden Routine erst in der abgeleiteten Klasse bekannt ist.

      Folgendes Beispiel:
      es gibt ein Projekt "Personen", bestehend aus einem DL, einem BL und mehreren PL. Mehrere PL, weil es zum einen die "normale" Personenmaske geben kann, zum anderen aber z. B. eine Personenmaske zur Schnelleingabe, eine die als Usercontrol in einer anderen Maske eingebunden ist, etc.

      Hier werden zum Laden und zur Anzeige der Daten jeweils andere Funktionen im BL (und DL) aufgerufen.
      SetNewRecord soll aus den verschiedenen Masken/Usercontrols jeweils die entsprechende Laderoutine aufrufen, um sich eine leere Datenstruktur zu ermitteln.

      Das einzige Problem hierbei ist wie gesagt, dass es bei einer existierenden Überladung knallt, da die Funktion nicht mehr eindeutig zugewiesen werden kann.

      Versuche ich noch ein Array mit den Parametertypen, liefert die Methode mir Nothing zurück:
      me.GetType.GetMethod("MethodenName", Reflection.BindingFlags.ExactBinding, NOTHING, arrParmTypes, NOTHING)

      mfg
      CM

      Comment


      • #4
        Hallo C.Mark,

        ich bin ganz stark davon überzeugt, dass Reflection immer noch der falsche Ansatz ist. Das braucht man wirklich nur, wenn es um Attribute geht, oder wenn man ein Microkernel Prinzip aufbauen möchte.

        Bei Dir gibt es meiner Meinung nach 2 verschiedene Ansätze, um Dein Problem zu lösen:

        A (sehr unschön):
        Du gibst als Parameter notwendige Delegate-Definitionen mit, um dann aus der Basisklasse heraus die dynamischen Aufrufe zu erledigen. Der Konstruktor der konkreten Klasse (Kindklasse) muss dann diesen unterschiedlichen Konstruktor aufrufen, um die Delegates festzulegen.

        B (wesentlich schöner):
        Du definierst Interfaces. Hier kannst Du die Methoden definieren, die aufrufbar sind. Dann kann die Basisklasse direkt die Methoden aufrufen, ohne die konkrete Implementierung zu wissen.

        Es ist (fast) immer ein Designfehler, wenn eine Basisklasse Wissen über eine Kindklasse haben muss, damit es funktioniert.

        Der Sinn einer Basisklasse ist hier immer gemeinschaftliche Dinge zusammenzufassen. Wenn nun die Kindklasse Spezifikationen definieren muss, dann ist es eigentlich keine Basisfunktionalität mehr.

        Du kannst aber Methoden als abstrakt definieren. So kannst Du z.B. das Laden und Speichern der Personendaten in der Basisklasse so definieren:

        Code:
        Public MustInherit Class PersonBase
        
           Public MustOverride Sub LoadData(p_Data as DataSet)
        
           Public MustOverride Sub SaveData() as DataSet
        
        End Class
        Es ist ein schwieriges Kapitel, ich hab z.B. einen komplizierten Artikel hier gefunden, der das vielleicht etwas näher erläutert:

        Doing Objects in VB.NET (englisch)

        Ein weiteres Stichwort könnte auch "AbstractFactory Pattern" sein, das sich am Rande auch mit einer Problemlösung deines Problems beschäftigt.

        Auf jeden Fall solltest Du von Reflection abkommen, glaub mir, in Deinem Fall ist das Evil ;-)

        Viele Grüße
        _ntr_

        Comment


        • #5
          Das kling auch alles aus meiner Sicht nicht richtig. Reflection ist der völlig falsche Ansatz. Wieso verwendest Du keine Delegates. Die wären dafür eine Lösung.
          Gruss

          Mirko

          Mappen statt hacken mit dem .NET O/R Mapper Invist

          Comment

          Working...
          X