List(Of T) - Kann Integer nicht um 1 erhöhen

  • VB.NET

Es gibt 15 Antworten in diesem Thema. Der letzte Beitrag () ist von ErfinderDesRades.

    List(Of T) - Kann Integer nicht um 1 erhöhen

    Hi,

    heute Morgen bin ich auf folgendes Problem gestoßen:
    Ich kann ein Integer aus einer Liste, die über die Parameter von einem Event geliefert wurde nicht um 1 erhöhen.

    So wird die Liste deklariert:

    VB.NET-Quellcode

    1. Private Shared entries As List(Of Struktur)


    So sieht die Struktur aus:

    VB.NET-Quellcode

    1. Public Structure Struktur
    2. Public Property Control As Control
    3. Public Property Count As Integer
    4. End Structure


    So möchte ich den Wert "Count" um 1 erhöhen:

    VB.NET-Quellcode

    1. For Each s As Struktur In entries
    2. s.Count = s.Count + 1
    3. Next


    Die Methode, wo der Eintrag geändert wird, ist shared.

    Ich würde mich über Hilfe freuen :)

    LG, Trudi
    Hi,
    da habe ich etwas gekürzt, die ganze Definition lautet so:

    VB.NET-Quellcode

    1. Private Shared entries As List(Of Struktur) = New List(Of Struktur)


    Wahrscheinlich hat es etwas mit dem Shared zu tun, leider ist dies aber unvermeidbar.
    ich bin mir nicht sicher aber ich glaube das hat etwas damit zutun, dass eine structure anders behandelt wird als eine klasse.. ob es was mit wertetyp und referenz zutun hat weiß ich nicht, mal abwarten ob jemand mit mehr wissen was dazu schreibt.

    auf jedenfall funst das hier nicht:

    For i as integer = 0 To entries.Count - 1
    entries(i).Count += 1
    Next

    ..obwohl es ja genau das gleiche macht wie die for-schleife.
    aber eine klasse hat doch nur vorteile, du kannst für count einen startwert festlegen (da braucht man ihn zwar nicht da = 0 aber bei andren variablen ist das ja schon nützlich)

    EDIT: ich galube das ist die antwort:
    openbook.galileocomputing.de/v…e44a09977a46535c1de2827b1
    Es liegt an der Referenz. Bei einer Klasse wird der Countwert in die Klasse geschrieben, da sie bei der For Schleife als Referenz genommen wird. Bei einer Struktur ists wie gesagt eben nur eine Struktur. In der Schleife wirst du den erhöhten Count auslesen können, aber der wird nicht in dem List Eintrag geändert.

    Trudi schrieb:

    In C++ sind Strukturen das Selbe wie Klassen

    Das liegt daran, weil C++ den Speicher komplett anders verwaltet.
    In .Net (ALLE Net Sprachen!) werden Referenztypen auf dem Heap und Werttypen auf dem Stack angelegt. Muss ein Werttyp als Referenztyp verwendet werden - zb weil er in einer List(of T) steckt! - dann wird eine KOPIE auf dem Heap erzeugt. Wenn man "Glück" hat, meckert schon der Compiler. Wenn man Pech hat, hat man etwas das zwar kompiliert, aber nicht macht, was man will. zB wenn man einen Wert zuweist, aber der in der Kopie landet, so dass das ursprüngliche Objekt seinen alten Wert behält!
    Du hast ein array (keine liste).
    Machst dann das:

    Array.Reverse(DeinArray)
    Array.Resize(DeinArray, DeinArray.Count + 1)
    Array.Reverse(DeinArray)

    Das dreht den array um, macht ein "leeres" feld hinten dran, und dreht es wieder richtig,
    so hast du ein "leeres" feld am anfang.
    Ich glaube, das ist, was du suchst, kann das sein?^^
    ein Referenz-Objekt (Class) ist eine Art Zeiger auf eine Instanz, während eine Structur die Instanz selber ist.

    Also eine List(Of DeineStructur) enthält tatsächlich ganz viele deiner DeineStructur-Dinger hintereinander.

    Hingegen bei einer List(Of DeineClass) fahren die DeineClass-Instanzen iwo im Speicher herum, und in der Liste befinden sich nur Zeiger darauf.

    Wenn du also von der Struct-List eine Structur abrufst, erhälst du eine Kopie. Da kannst du schön den Counter erhöhen, das interessiert die Original-Struktur inne Struct-List herzlich wenig.

    Wenn du hingegen von der Class-List ein Objekt abrufst, erhälst du einen Zeiger. Da kannst du schön den Counter erhöhen, und weil der Zeiger inne Class-List auf dieselbe Instanz zeigt, ists da auch geändert.
    Etwas "komplizierter" ist es schon ... ;)

    Stichwort: Boxing.

    zB hier:
    msdn.microsoft.com/en-us/library/aa289521(v=vs.71).aspx

    Wichtig zb:
    A Visual Basic .NET Collection object stores all its elements as type Object. Therefore, if you use structures as the elements of such a collection, you incur overhead for boxing and unboxing.

    An array of structures is already a reference type, so it does not undergo boxing when assigned or passed to an Object.

    Dadurch ergibt sich ein verändertes Verhalten, je nachdem ob ich meine Structure in einem Array oder einer Collection ablege.

    Sehr "schöner" Fehler zb hier:
    vb-paradise.de/programmieren/h…e-member-variable-aendern
    Programm kompiliert und läuft, aber es macht nicht was es soll!

    Deswegen sollte man (IMHO) Structures nur dann einsetzen, wenn man 150% genau weiß, was man tut!

    picoflop schrieb:

    Dadurch ergibt sich ein verändertes Verhalten, je nachdem ob ich meine Structure in einem Array oder einer Collection ablege.

    Das glaubich noch nicht ganz. Ich denke, MSDN bezieht sich da explizit auf die Microsoft.VisualBasic.Collection - Klasse, die eh verboten gehört.

    Aber die modernen generischen Auflistungen wrappern alle ein Array, und daher erwarte ich von dene nicht, dass die da auf einmal mit Boxing anfangen.