none
Auf Felder und Methoden einer Klasse mithilfe einer Variable zugreifen RRS feed

  • Frage

  • Guten Morgen,

    ich habe ein kleines Problem, und zwar möchte ich mithilfe einer Variable (die während der Laufzeit verändert wird) auf Felder und Methoden einer Klasse zugreifen.

    Ich habe zum Beispiel: 

    string Value = "ConfigManager.Manager.User.UserManager";

    (ConfigManager = Projektname, Manager = Ordner in dem sich der Ordner User befindet, User = Ordner in dem sich die Klasse UserManager befindet)

    Nun enthält die Klasse UserManager eine ObservableCollection mit dem Namen "Collection". Wie kann ich auf diese Collection zugreifen? Weil ich kann nicht einfach schreiben: 

    value.Collection[0].displayName;

    Danke für Eure Hilfe! :)
    Lukas


    • Bearbeitet Skeptar Mittwoch, 11. November 2015 08:59
    Mittwoch, 11. November 2015 08:53

Antworten

  • Hi Lukas,
    ein Programm hält seine Daten im Speicher (RAM) und nur auf diese Daten kann die CPU mittels Adresse zugreifen, um dann Operationen auszuführen. Um auf konkrete Daten zuzugreifen, werden Speicherbereiche strukturiert und bereits zur Entwurfszeit ist bekannt, an welcher (relativen) Adresse im Speicher sich die gewünschten Daten befinden.

    Dieses Grundprinzip wird in .NET umgesetzt, indem die Strukturierung des Speicherbereiches in Klassen deklariert (spezifiziert) wird. Zu diesem Zeitpunkt ist noch nicht bekannt, wo sich die Daten dann wirklich im Speicher befinden werden. Die Klasse ist nur ein Muster, welches dann auf den Speicherbereich "gelegt" wird. Zur Ausführungszeit wird der konkrete Speicherplatz zugewiesen, indem während des Programmlaufes Objekte vom Typ der deklarierten Klassen erzeugt werden (new, Instanziierung). Jedes Objekt hat dann eine "Basis-Adresse" (Verweisadresse), zu der sich relativ (Verschiebung) die konkreten Inhalte des Objektes befinden. Der Compiler übersetzt das Programm und organisiert den Zugriff auf die Daten, indem er auf Basis der Klassendeklaration die Verschiebung zur Basisadresse des Objektes in die exe/dll schreibt. Die Basisadresse selbst muss zur Ausführungszeit in einer Verweisvariablen bekannt sein. Diese bekommt das Programm im Ergebnis der Instanziierung (new) oder wird statisch bereitgestellt (static / Shared).

    Mit dieser Arbeitsweise wird sichergestellt, dass in jedem Schritt auch typsicher der richtige Speicherbereich adressiert wird. Eine Alternative ist die Reflection. Aber auch da muss die Verweisvariable bekannt sein. Die konkrete Adresse wird dann durch Analyse der Metainformation (praktisch ist das ein Abstrakt der Klassendeklaration) ermittelt. das ist aber recht langsam.

    Formuliere mal Deine Frage etwas genauer, nachdem Du Dich etwas tiefer mit der objektorientierten Programmierung auseinander gesetzt hast.


    --
    Viele Grüsse
    Peter Fleischer (MVP, Partner)
    Meine Homepage mit Tipps und Tricks
    Kommas richtig setzen!
    Schüler sagen, Lehrer haben es gut.
    Schüler, sagen Lehrer, haben es gut

    • Als Antwort markiert Skeptar Mittwoch, 11. November 2015 09:39
    Mittwoch, 11. November 2015 09:12

Alle Antworten

  • Hallo Lukas,

    im Moment kann ich dir noch nicht ganz folgen.

    Eine Variable erstellen, um mit dieser auf Methoden und Felder zugreifen zu können welche sie beinhaltet erstellt man einfach mit:

        public class meineKlasse
        {
            public int Wert1 { get; set; }
            public int Wert2 { get; set; }
            public int Ergebnis { get; private set; }
    
            public void ErgebnisGenerieren()
            {
                Ergebnis = Wert1 + Wert2;
            }
        }
    
        public class meinProgramm
        {
            public meinProgramm()
            {
                meineKlasse variable = new meineKlasse();
                variable.Wert1 = 2;
                variable.Wert2 = 3;
    
                variable.ErgebnisGenerieren();
    
                Console.WriteLine("Ergebnis {0}", variable.Ergebnis);
            }
        }

    Mittwoch, 11. November 2015 09:04
  • Hi Lukas,
    ein Programm hält seine Daten im Speicher (RAM) und nur auf diese Daten kann die CPU mittels Adresse zugreifen, um dann Operationen auszuführen. Um auf konkrete Daten zuzugreifen, werden Speicherbereiche strukturiert und bereits zur Entwurfszeit ist bekannt, an welcher (relativen) Adresse im Speicher sich die gewünschten Daten befinden.

    Dieses Grundprinzip wird in .NET umgesetzt, indem die Strukturierung des Speicherbereiches in Klassen deklariert (spezifiziert) wird. Zu diesem Zeitpunkt ist noch nicht bekannt, wo sich die Daten dann wirklich im Speicher befinden werden. Die Klasse ist nur ein Muster, welches dann auf den Speicherbereich "gelegt" wird. Zur Ausführungszeit wird der konkrete Speicherplatz zugewiesen, indem während des Programmlaufes Objekte vom Typ der deklarierten Klassen erzeugt werden (new, Instanziierung). Jedes Objekt hat dann eine "Basis-Adresse" (Verweisadresse), zu der sich relativ (Verschiebung) die konkreten Inhalte des Objektes befinden. Der Compiler übersetzt das Programm und organisiert den Zugriff auf die Daten, indem er auf Basis der Klassendeklaration die Verschiebung zur Basisadresse des Objektes in die exe/dll schreibt. Die Basisadresse selbst muss zur Ausführungszeit in einer Verweisvariablen bekannt sein. Diese bekommt das Programm im Ergebnis der Instanziierung (new) oder wird statisch bereitgestellt (static / Shared).

    Mit dieser Arbeitsweise wird sichergestellt, dass in jedem Schritt auch typsicher der richtige Speicherbereich adressiert wird. Eine Alternative ist die Reflection. Aber auch da muss die Verweisvariable bekannt sein. Die konkrete Adresse wird dann durch Analyse der Metainformation (praktisch ist das ein Abstrakt der Klassendeklaration) ermittelt. das ist aber recht langsam.

    Formuliere mal Deine Frage etwas genauer, nachdem Du Dich etwas tiefer mit der objektorientierten Programmierung auseinander gesetzt hast.


    --
    Viele Grüsse
    Peter Fleischer (MVP, Partner)
    Meine Homepage mit Tipps und Tricks
    Kommas richtig setzen!
    Schüler sagen, Lehrer haben es gut.
    Schüler, sagen Lehrer, haben es gut

    • Als Antwort markiert Skeptar Mittwoch, 11. November 2015 09:39
    Mittwoch, 11. November 2015 09:12
  • Hallo David,

    danke für die fixe Antwort! :)

    Also ich versuche es mal zu erklären.

    Ich habe ein TabControl mit verschiedenen TabItems. Jedes TabItem hat von mir einen DataContext in der MainWindow.xaml Datei zugewiesen bekommen. Zudem existiert eine ToolBar mit verschiedenen Operationen (remove selected, select all, unselect all). Die Operationen in der ToolBar sollen für alle DataGrids gehen (in jedem TabItem befindet sich ein DataGrid!). In jedem DataGrid wird eine ObservableCollection dargestellt mithilfe eines Bindings.

    http://img5.fotos-hochladen.net/uploads/asdoxpknaicds.png

    Nun gibt es nicht nur das DataGrid für die User sondern auch z.B. für die Gruppen oder RemoteDesktops. Nun habe ich keine Lust in jeder Klasse 3 Funktionen - die von der Logik her gleich sind - zu schreiben. Deswegen dachte ich mir nehme ich mir die Übergeordnete Klasse und finde heraus welche Liste gerade angezeigt wird, mithilfe des DataContextes. Und über den DataConext weiß ich welche Liste gerade angezeigt wird und bei welcher ich die Operationen ausführen muss. 

    Nun habe ich beim ersten Button "select all" den DataConext ausgelesen von dem gewählten TabItem ausgelesen: 

    private void btnSelectAll_Click(object sender, RoutedEventArgs e) { TabItem selectedTabItem = (TabItem)this.tc.SelectedItem; string classPath = selectedTabItem.DataContext.ToString(); }

    In classPath steht also nun "ConfigManager.Manager.User.UserManager". Und in der Klasse UserManager befindet sich die ObservableCollection mit dem Namen Collection, auf die ich nun zugreifen möchte, mithilfe der Variable

    Ich hoffe man kann mich verstehen. :P



    • Bearbeitet Skeptar Mittwoch, 11. November 2015 09:30
    Mittwoch, 11. November 2015 09:23
  • Hallo Peter,

    danke für deine Antwort!

    Meine Verweise 

    [XmlElement("UserManager")]
            public UserManager UserManager { get; set; }
    
    [XmlElement("GroupManager")]
            public GroupManager GroupManager { get; set; }

    heißen so wie die Klassen heißen. Sprich der Verweis hat den Namen UserManager und die Klasse hat auch den Namen UserManager.

    Wäre es also möglich wenn die Variable UM = "UserManager"; existiert anstatt

    UserManager.Collection[0].DisplayName;
    ->
    UM.Collection[0].DisplayName
    zu schreiben?




    • Bearbeitet Skeptar Mittwoch, 11. November 2015 09:47
    Mittwoch, 11. November 2015 09:39
  • Hallo Lukas,

    Ich glaube nun verstanden zu haben wo dein Problem liegt. Ich habe vor wenigen Tagen vor der gleichen/ähnlichen Herausforderung gestanden. Ich arbeite auch mit mehreren Tabs und muss dann entsprechend Funktionen im übergeordneten Menü zur Verfügung stellen und dafür muss ich natürlich wissen welches Tab gerade das aktive ist etc.

    Meine Lösung habe ich hier im Thread veröffentlicht.

    Mittwoch, 11. November 2015 09:45
  • Hi,
    die Grundidee, die ich realisieren würde, ist eine Registrierung der später benötigten Objekte (z.B. Deine TabItems, Deine ViewModels, Deine Datenpuffer). Wenn jetzt etwas benötigt wird, brauchst Du nur einen Schlüssel, um aus den Registrierungen das gewünschte Objekt zu holen (Objektverweis). Wenn z.B. die Basisklasse des ViewModels wissen will, welche konkrete ViewModel-Instanz gerade aktiv ist, wird eine ID (z.B. GUID) genutzt, um aus den registrierten Objekten den Verweis auf das gewünschte Objekt zu bekommen.

    --
    Viele Grüsse
    Peter Fleischer (MVP, Partner)
    Meine Homepage mit Tipps und Tricks
    Kommas richtig setzen!
    Schüler sagen, Lehrer haben es gut.
    Schüler, sagen Lehrer, haben es gut

    Mittwoch, 11. November 2015 10:17
  • Hi,
    Bezeichnung einer Member gleich wie der Typ zu nutzen, ist keine gute Idee. Das kann Probleme bereiten, wenn zusätzlich teilweise statisch gearbeitet werden kann. Außerdem wird das Programm unübersichtlich. Alternativ wäre so etwas möglich:

    [XmlElement("UserManager")]
            public UserManager UM{ get; set; }
    
    ...
    
    UM.Collection[0].DisplayName
    


    --
    Viele Grüsse
    Peter Fleischer (MVP, Partner)
    Meine Homepage mit Tipps und Tricks
    Kommas richtig setzen!
    Schüler sagen, Lehrer haben es gut.
    Schüler, sagen Lehrer, haben es gut

    Mittwoch, 11. November 2015 11:34