Referenz auf Objekt zurückgeben



  • Hi Leute, ich habe ein kleines Problem und weiß nicht, wie ich es in C# lösen kann. Ich bin gerade auf C# umgestiegen und möchte mir eine kleine Anwendung programmieren.

    Es wird eine SDI-Anwendung mit einem Haupformular sowie zwei kleinen Subformularen. Die Daten für diese Anwendung werden in einem DataSet (Inhalt: 4 Tabellen) gehalten, welches in eine XML-Datei gespeichert wird. Das DataSet kapsel ich in einer Klasse, die zum Zugriff auf das DataSet benutzt wird. Von dieser Klasse (TableProxy) erstelle ich eine Instanz in meinem Hauptformular (zum Anzeigen und Auswählen der Daten). Die zwei kleineren Formulare dienen dem Hinzufügen und Bearbeiten der Daten. Vor dem Hinzufügen der Daten muss jeweils geprüft werden, ob ein Eintrag mit dem Namen schon existiert.

    Eine Möglichkeit wäre, bevor ich die kleineren Formulare aufrufe, das DataSet erst in die XML-Datei zu speichern und dann wieder in dem Neben-Formular zu laden. Das ist aber nicht wirklich performant.

    Die andere Möglichkeit, die ich vorhatte, ist vielleicht ein wenig unsauber, aber naja... Ich wollte mir aus der Klasse TableProxy eine Referenz auf das entsprechende System.Data.DataTable-Objekt zurückgeben lassen (mittels DataSet.Tables[index]). Dieses wollte ich per Referenz (ref) an den Konstruktor des entsprechenden Formulars übergeben. Somit hätte ich direkten Zugriff auf die Tabelle gehabt. Leider bekomme ich es nicht hin. Wie mache ich das?

    //Haupt-Formular
    private void showZutatDialog()
    {
       ZutatForm zutat = new ZutatForm(this.tableProxy.getTable(1));
       zutat.ShowDialog();
    }
    
    //TableProxy
    public System.Data.DataTable getTable(int index)
    {
       return this.cocktailerDataSet.Tables[index];
    }
    
    //ZutatForm -> Nebenformular
    public ZutatForm(ref System.Data.DataTable zutatTable)
    {
       ...
    }
    
    Fehlermeldung: Ein 'ref'- oder 'out'-Argument muss ein 'lvalue' sein
    

    Was mache ich grundsätzlich falsch? Gibt's vielleicht einen saubereren bzw. besseren Weg?

    Viele Grüße, Stefan



  • Du übergibst dem Konstruktor, der einen Referenzparameter erwartet this.tableProxy.getTable(1). Das ist aber eine Funktion, der natürlich kein Wert zugewiesen werden kann. Also vorher das Objekt mit getTable(1) aufrufen und danach dieses übergeben.
    Vorausgesetzt, dass du das Objekt mit setTable zurückspeichern kannst :

    private void showZutatDialog() {
        System.Data.DataTable table = this.tableProxy.getTable(1);
        ZutatForm zutat = new ZutatForm(ref table);
        this.tableProxy.setTable(1,table);
        zutat.ShowDialog(); 
    }
    


  • Ok, das funktioniert. Aber wenn ich dann dem Konstruktor das so, wie du's geschrieben hast übergebe, übergebe ich dann auch wirklich eine Referenz auf das DataTableObjekt (also wird durch "return this.cocktailerDataSet.Tables[index];" eine Adresse zurückgegeben (keine Kopie???))? Wenn ich dann was in der ZutatForm ändere, ist das dann auch in dem DataSet geändert?

    MFG Stefan

    Edit: Stopp, hab's gerade gelesen! Ich muss das zurückspeichern!!! Gibt's keine Möglichkeit wie in C++, so dass ich "return &..." mache und somit direkt mit dem Objekt in dem DataSet arbeite?



  • Ach so, ich hab mich im Code oben geirrt. Klassen werden sind bei C# ja standardmäßig Verweistypen und structs Werttypen. Also muss das Objekt nicht mit SetTable zurückgespeichert werden. Du kannst also sicher sein, dass du bei einer Zuweisung auf eine Objektvariable eine Referenz zu der anderen Klasse hast.

    private void showZutatDialog() {
        System.Data.DataTable table = this.tableProxy.getTable(1);
        ZutatForm zutat = new ZutatForm(ref table);
        zutat.ShowDialog(); 
    }
    


  • Supi, danke! Dann werde ich's wohl so lösen.
    Für sauberere Vorschläge bzw. Anwendung von irgendwelchen Patterns bin ich natürlich weiterhin offen. Schließlich ziehe ich hier aus einem Objekt ein anderes Objekt raus und manipuliere es wieder in einem anderen Objekt 😉
    Ich habe immer mal so Probleme, wie ich den Zugriff auf solche Klassen lösen kann, in denen ich alle Daten speicher.

    MFG Stefan

    Edit: Nochmal 'ne Frage: Das geht also sicher nicht, dass ich als
    Parameter einen Funktionsaufruf übergebe (da diese Funktion schließlich den gewünschten Parameter zurückgibt)? Ist eigentlich schade! In C++ war das doch immer so schön möglich. Aah, gerade nochmal ausprobiert. Geht nur nicht mit ref. Warum?


Anmelden zum Antworten