Frage zur Referenz oder Zeiger



  • ich habe ein ArrayList Element in dem verschiedene Informationen als sturktur abgespiechert werden.
    Jetzt möchte ich auf ein element zugreifen.
    Normaleweise kann man es so schreiben:

    struct sInfoFeld
    {
    string Info;
    }
    string Info1 = ((sInfoFeld)MyArray[i]).Info1;

    Ich habe mich unter c++ daran gewöht jedoch mir einen Zeiger geben zu lassen oder die Referenz:

    sInfoFeld *pInfo1 = ((sInfoFeld)MyArray[i]);
    string Info1 = pInfo1->Info1;

    Sind die Strukturen noch komplexer so erspare ich mir bei jedem Zugriff den Cast Operator:

    struct sInfoFeld
    {
    string Info;
    ArrayList InfoStatus;
    }

    Ich würde gerne meine Methode auch unter c# verwenden weiss aber nicht ob bei der Zuweisung eine Kopie, Refernez, Zeiger übergeben wird.

    sInfoFeld Info1 = ((sInfoFeld)MyArray[i]);

    Was wird hier erzeugt? Oder was gibt es für alternativen?



  • Warum nimmst Du nicht einfach typisierte Listen (z.B. List<..>)?



  • Benutze class statt struct, dann hast Du Referenz- statt Wertesemantik.

    Das löst Dein Problem.

    Du hast aber noch einige andere. Warum zur Hölle programmierst Du C in C#?

    Protipp: Mit dem unsafe Schlüsselwort und dem entsprechenden Compilerschalter kannst Du Zeiger in C# verwenden. Das versaut Deinen Stil entgültig 😃


  • Administrator

    Man greift ja nicht mal unter C++ so auf die Elemente zu.

    struct test { int i; };
    
    test arr[10];
    
    arr[0].i = 10;
    int x = arr[0].i;
    

    Keinerlei Konvertierungen!

    Wenn du typisierte Container verwendest, dann ist das auch in C# unnötig.

    Michael S. schrieb:

    Was wird hier erzeugt?

    Es findet ein unboxing statt, sofern du wirklich ArrayList verwendest, und es wird eine Kopie gemacht.

    Michael S. schrieb:

    Oder was gibt es für alternativen?

    Was ist dein genaues Ziel? Das kommt aus deinem Beitrag nicht klar herrüber. Nur einen Zugriff auf das Element? Dann eben die typisierten Listen verwenden:
    http://msdn.microsoft.com/en-us/library/system.collections.generic.aspx

    Grüssli



  • Natürlich verwende ich keinen einfachen structs.
    Bei mir sehen sie so aus:

    struct sInfo{
    int Info1;
    ...
    ArrayList InfoStatus; // andere Struktur sInfoStatus
    ArrayList InfoStatus2;
    usw.
    }

    ArrayList sInfo

    Jetzt suche ich in mein algoritmus nach einem sInfo Element aus Array. Wenn ich es gefunden habe möchte ich später direkten Zugriff drauf haben, also speichere ich mir entweder den Index oder aus C++ bekannt den Zeiger. Wie

    int nIdx = FindeInfoIdx(); // c#

    sInfo pFindInfo = FindeInfo(); // aus C++

    Ich möchte jetzt aus dem gefundenen sInfo Element die InfoStatus duchsuchen:

    int Status1= ((sInfoStatus)((sInfo)Liste[nIdx]).InfoStatus[j]).Status1;

    Diese lange Zeile will ich vermeiden.

    In c++ hätte ich über den Zeiger diese Lösung:

    int Status1 = pFindInfo->InfoStatus[j].Status1;

    Jetzt ist die schreibweise etwas kürzer:

    int Status1 = pFindInfo->InfoStatus[j].Status1;
    int Status2 = pFindInfo->InfoStatus[j].Status2;
    int Status3 = pFindInfo->InfoStatus[j].Status3;

    Wenn ich jedoch viele Status hollen möchte sieht es so aus

    sStatusInfo pStatus = pFindInfo->InfoStatus[j]
    int Status1 = pStatus->Status1;
    int Status2 = pStatus->Status2;
    int Status3 = pStatus->Status3;

    Ich sage nicht dass ich es unter c# auch so verwenden muss. Ich suche nur nach bessere möglichkeiten als

    int Status1= ((sInfoStatus)((sInfo)Liste[nIdx]).InfoStatus[j]).Status1;
    int Status2= ((sInfoStatus)((sInfo)Liste[nIdx]).InfoStatus[j]).Status2;
    int Status3= ((sInfoStatus)((sInfo)Liste[nIdx]).InfoStatus[j]).Status3;

    denn wenn ich so schreibe:
    sInfo Info = (sInfo)Liste[nIdx];
    sInfo InfoStatus = ((sInfoStatus)Info.InfoStatus[j]);
    int Status1= InfoStatus.Status1;
    int Status2= InfoStatus.Status2;
    int Status3= InfoStatus.Status3;
    dann werden kopien angelegt (schlecht will ich nicht)

    Wenn ich es richtig verstanden habe ist anstatt einer Struct eine Klasse bessere Lösung da hier:
    CInfo Info = (CInfo)Liste[nIdx];
    CInfoStatus InfoStatus = (CInfoStatus)Info.InfoStatus[j];
    referenzen angelegt werden.

    Oder was meint ihr noch dazu?
    (Natürlich kann die Struktur noch komplexer werden dass im sInfoStatus weitere Arrays abgelegt werden)



  • Wie schon gesagt wurde, verwende eine Klasse, statt einer Struktur, dann wird auch keine Kopie erstellt. Allgemein verstehe ich deinen ultimativen Zugriff sowieso nicht. Wir wissen nichtmal welchen Typ deine "Liste" hält und deine Casts sehen extrem aus.



  • Ich komme auch von C++ nach C#, deshalb auch von mir der Tip: Beschäftige dich etwas mit der Box/Unboxing-Problematik. Das macht einiges klar, u.a. was Zeiger bzw. Referenzen für eine Rolle spielen. Und wenn du die richitgen Interfaces implementierst, kannst du sau-eleganten code in 2-3 Zeilen schreiben, wofür man in C++ das 10-20fache braucht... aber soweit bin ich auch noch nicht... 😃


Anmelden zum Antworten