Funktion "AddToArray" in vb.net

OP #7916580
Lesenswert?

Hey Leute,

Folgendes Problem: Ich möchte immer wiedermal etwas zu einem Array hinzufügen. An und für sich nicht aufregendes.

Nur diesmal: Die Datentype soll egal sein.

Folgedes gibts schon: Array erweitern Verwendung: "ExpandArray(Countries)"

1
    Public Sub ExpandArray(Of T)(ByRef Arrayy() As T)
2
        If IsNothing(Arrayy) Then
3
            ReDim Arrayy(-1)
4
        End If
5
        ReDim Preserve Arrayy(UBound(Arrayy) + 1)
6
    End Sub

Einen Eintrag im Array löschen Verwendung: "RemoveAt(Lines, i - 1)"

1
  Public Sub RemoveAt(Of T)(ByRef a() As T, ByVal index As Integer)
2
        ' Move elements after "index" down 1 position.
3
        Array.Copy(a, index + 1, a, index, UBound(a) - index)
4
        ' Shorten by 1 element.
5
        ReDim Preserve a(UBound(a) - 1)
6
    End Sub

Die Verwendung der neuen Funktion sollte so aussehen:

1
dim NewCountry as new CountryStruct
2
NewCountry. Name = "SeppelLand"
3
AddToArray(Countries,NewCountry)

Also: Kennt wer einen Code, der das für mich bereitstellt?

(Firma: Jasinski) #7916738
Lesenswert?

Ate E. schrieb:

Folgendes Problem: Ich möchte immer wiedermal etwas zu einem Array hinzufügen. An und für sich nicht aufregendes. Nur diesmal: Die Datentype soll egal sein.

Schon mal mit Object und 'List of Object' versucht zu arbeiten? Damit kann man eigentlich mit beliebigen Datentypen arbeiten (auch Delegaten) und sogar Arrays, Objekte oder Listen selbst in einer Liste unterbringen, manipulieren oder löschen. Und nicht vergessen: ganz wichtig beim deklarieren/erstellen einer neuen Liste ist das 'New' davor.

1
Public Structure MyStruc_struc
2
    Dim Land As String
3
    Dim Anzahl As Integer
4
End Structure
5

6
'(in einer Sub, Function etc.)
7
Dim MyArray As Array = {1, 2, 3, 4}
8
Dim MyStruc As MyStruc_struc
9
MyStruc.Land = "DE"
10
MyStruc.Anzahl = 80
11
Dim MyObj As Object = 3.14F 'Single
12
Dim MyList As New List(Of List)
13

14
Dim ObjList As New List(Of Object) 'das ist die eigentliche Liste (*)
15

16
'--- beliebige Datentypen zu Liste hinzufügen
17
ObjList.Add("Atari") 'String hinzufügen
18
ObjList.Add(1.4R) 'Double hinzufügen
19
ObjList.Add(100) 'Integer hinzufügen
20
ObjList.Add(MyArray) 'ganzes Array als Objekt hinzufügen
21
ObjList.Add(MyStruc) 'ganze Struc als Objekt hinzufügen
22
ObjList.Add(MyObj) 'Object als Objekt hinzufügen
23
ObjList.Add(MyList) 'List als Objekt hinzufügen
24

25
'--- abfragen
26
DEBUG_tbox1.Text &= ObjList.IndexOf("Atari").ToString & ", "
27
DEBUG_tbox1.Text &= ObjList.IndexOf(1.4R).ToString & ", "
28
DEBUG_tbox1.Text &= ObjList.IndexOf(100).ToString & ", "
29
DEBUG_tbox1.Text &= ObjList.IndexOf(MyArray).ToString & ", "
30
DEBUG_tbox1.Text &= ObjList.IndexOf(MyStruc).ToString & ", "
31
DEBUG_tbox1.Text &= ObjList.IndexOf(MyObj).ToString & ", "
32
DEBUG_tbox1.Text &= ObjList.IndexOf(MyList).ToString & ", "
33

34
'--- manipulieren, löschen etc.
35
ObjList.Remove("Atari")
36
ObjList.RemoveAt(ObjList.IndexOf(MyStruc))
37
'oder so: ObjList.Remove(MyStruc)
38

39
DEBUG_tbox1.Text &= ObjList.IndexOf("Atari").ToString & ", "
40
DEBUG_tbox1.Text &= ObjList.IndexOf(MyStruc).ToString & ", "
(Firma: 1984now) #7917261
Lesenswert?

Ate E. schrieb:

Kennt wer einen Code, der das für mich bereitstellt?

Nur ein Teil. Das Entfernen eines Elements müsstest du selber noch nachrüsten.

[Code] Public Class ExpandebleArray(Of T) Private a As T()

1
Public ReadOnly Property BaseArray As T()
2
    Get
3
        Return a
4
    End Get
5
End Property
6
Public ReadOnly Property Length As Integer
7
    Get
8
        Return a.Length
9
    End Get
10
End Property
11
Default Public Property Item(Index As Integer) As T
12
    Get
13
        Return a(Index)
14
    End Get
15
    Set(value As T)
16
        a(Index) = value
17
    End Set
18
End Property
19

20
Public Sub Append(NewElement As T)
21
    ReDim Preserve a(a.Length)
22
    a(a.Length - 1) = NewElement
23
End Sub
24

25
Public Sub New(InitialLastElementIndex As Integer)
26
    a = New T(InitialLastElementIndex) {}
27
End Sub

End Class [/Code]

Aber: Die ganze Sache ist eigentlich komplett sinnlos. Wenn solche Anforderungen an die Funktionalität bestehen, nimmt man statt eines Array natürlich gleich eine List(of <gewünschter Datentyp>). Da ist das alles schon eingebaut und zwar deutlich effizienter als es dieser teilweise Nachbau auf Basis eines Array leisten kann.

(Firma: Jasinski) #7917271
Lesenswert?

Ob S. schrieb:

Aber: Die ganze Sache ist eigentlich komplett sinnlos. Wenn solche Anforderungen an die Funktionalität bestehen, nimmt man statt eines Array natürlich gleich eine List(of <gewünschter Datentyp>). Da ist das alles schon eingebaut und zwar deutlich effizienter als es dieser teilweise Nachbau auf Basis eines Array leisten kann.

Und durch den Gebrauch von bereitgestellten und richtigen Werkzeugen ist das auch weniger fehleranfällig, denn, wenn man anfängt Arrays in irgendeiner Art und Weise 'per Hand' zu redimensionieren bzw. selbst zu manipulieren, kann man schnell in einer Exception landen – nimmt man dagegen eine 'List Of', wird das alles automatisch (und fehlerfrei) im Hintergrund für uns erledigt, also passend aneinandergeschoben, gekürzt etc. Möchte man später an die Daten gelangen, kann man das Object entsprechend casten und daraus z.B. wieder die uns bekannte Struc machen. Ist der Datentyp unbekannt, muss man halt abfragen, was es von den bekannten Typen wirklich ist. Würde man auf eine List von zwei verschiedenen Threads zugreifen, muss man das zusätzlich mit z.B. SyncLock etc. multithreadsicher machen, sonst knallt es, wenn z.B. ein Thread in der Liste gerade etwas löscht und ein anderer gerade dabei ist, es zu lesen oder auch zu löschen. Es gibt aber auch spezielle Listen mit anderen Bezeichnungen für solche Fälle – Beispiel: ConcurrentQueue (FIFO) oder ConcurrentDictionary. Das ist aber nur für Speizalfälle gedacht, denn normalerweise wird alles von einem Thread heraus vollführt.

#7917277
Lesenswert?

Hallo von Ate E.,

schau' mal, hier gibt es ein Beispiel:

http://www.vb-fun.de/cgi-bin/loadframe.pl?ID=vb/tipps/tip0328.shtml

Der Code funktioniert, ist zwar grottenschlecht, aber didaktisch höchst wertvoll. :)

Inhaltlich kann man sich der Meinung von Gregor J. und Ob S. weiter oben nur anschließen.

Arrays sind aufgrund ihrer internen Darstellung in VB6, VBA und wohl auch allen moderneren VB-Derivaten nicht geeignet dynamische Strukturen abzubilden.

Der verlinkte Code ist ein Musterbeispiel zum Thema "Laufzeit von Algorithmen". Anhand des Codes, den man z.B. auf sein C:-Laufwerk loslässt, kann man auch als Nichtinformatiker gut lernen, warum man es SO nicht macht.

Viel Erfolg und gute Erkenntnisse!

(Firma: 1984now) #7917282
Lesenswert?

Ob S. schrieb:

[Code] Public Class ExpandebleArray(Of T) ... [/Code]

Ich hatte noch vergessen, die Verwendung für dein Beispiel aufzuzeigen:

[Code]

public Countries as new ExpandebleArray(of CountryStruct)(-1)

...

dim NewCountry as new CountryStruct NewCountry.Name = "SeppelLand" Countries.Append(NewCountry)

Print Countries(0).Name

[/Code]

(Firma: 1984now) #7918309
Lesenswert?

Gregor J. schrieb:

nimmt man dagegen eine 'List Of', wird das alles automatisch (und fehlerfrei) im Hintergrund für uns erledigt, also passend aneinandergeschoben, gekürzt etc. Möchte man später an die Daten gelangen, kann man das Object entsprechend casten

Man braucht überhaupt nichts casten, wenn man die (generische) List(of <Typ>) gleich mit dem richtigen Datentyp erzeugt. Dann passt das alles von Hause aus ohne jedes schwachsinnige gecaste.

List(of <untypisierter Bullshit AKA objekt>) ist was, was nur Idioten benutzen, die nicht in der Lage sind, ihre Daten vernünftig zu strukturieren.

(Firma: Jasinski) #7918320
Lesenswert?

Ob S. schrieb:

Man braucht überhaupt nichts casten, wenn man die (generische) List(of <Typ>) gleich mit dem richtigen Datentyp erzeugt. Dann passt das alles von Hause aus ohne jedes schwachsinnige gecaste.

List(of <untypisierter Bullshit AKA objekt>) ist was, was nur Idioten benutzen, die nicht in der Lage sind, ihre Daten vernünftig zu strukturieren.

Selbstverständlich muss man später passend casten, wenn man alle möglichen Typen samt Strukturen und nicht einfach nur eine Sorte eines bestimmten Typs in eine List packt – und genau davon war auch die Rede => einfach nochmal nachlesen und vor allem: Textpassagen nicht absichtlich im falschen Kontext benutzen.

(Firma: 1984now) #7918334
Lesenswert?

Gregor J. schrieb:

Selbstverständlich muss man später passend casten, wenn man alle möglichen Typen samt Strukturen und nicht einfach nur eine Sorte eines bestimmten Typs in eine List packt – und genau davon war auch die Rede

Nein.

=> einfach nochmal nachlesen

Ja, solltest du wirklich tun. Im OT wollte er nur zu einem Array namens "Contries" eine CountryStruct hinzufügen bzw. daraus löschen.

Was also spricht deiner Meinung nach dafür, nicht eine List(of CountryStruct) zu verwenden? Das musst du jetzt wirklich mal erklären...

(Firma: Jasinski) #7918352
Lesenswert?

Ob S. schrieb:

Im OT wollte er nur zu einem Array namens "Contries" eine CountryStruct hinzufügen bzw. daraus löschen.

Das war am Ende des Eröffnungsbeitrags nur sein Beispiel, wie er das üblicherweise tut oder sich vorstellen würde, es zu tun.


Was also spricht deiner Meinung nach dafür, nicht eine List(of CountryStruct) zu verwenden? Das musst du jetzt wirklich mal erklären...

Diese Aussage:

Ate E. schrieb:

Nur diesmal: Die Datentype soll egal sein.

Was auch immer der Autor mit „Die Datentype soll egal sein” gemeint hat, denn diese kurze Aussage ist insgesamt ziemlich nebulös bzw. nicht wirklich eindeutig, aber das soll er am besten schon selbst erklären bzw. präzisieren, wenn er will, ansonsten macht das weitere Reden darüber überhaupt keinen Sinn und für kindische Streitereien und Beschimpfungen wirst Du Dir einen passenden Forumskumpel suchen müssen – mit mir wird es nicht gehen.

(Firma: 1984now) #7918477
Lesenswert?

Gregor J. schrieb:

Diese Aussage:

Ate E. schrieb:

Nur diesmal: Die Datentype soll egal sein.

Was auch immer der Autor mit „Die Datentype soll egal sein” gemeint hat

Das war m.E. ziemlich eindeutig: er wollte das für Arrays bliebiger Element-Typen, ohne die Append- oder RemoveAt-Methode jedesmal neu schreiben zu müssen. Und er kannte wohl nicht List(of <type>).

Aber selbst für "gemischte" Typen gibt es praktisch niemals einen Anlass, sich auf die Ebene von Object-Elementen begeben zu müssen.

Irgendwas haben die Eleemnte immer gemeinsam, sonst würde es nämlich keinen Sinn ergeben, sie in einer gemeinsamen Liste zu verwalten. Und diese Gemeinsamkeiten sind typisch immer weit größer, als die Eigenschaften eines <objekt>.

Und genau hier greift die Architektur-Entscheidung: Will ich z.B. graphic primitives verwalten, mache ich das nicht in Form einer List(of object), sondern in Form einer List(of graphicprimitive). Natürlich kommt es dann vor, dass ich casten muss, im spezielle Eigenschaften oder Fähigkeiten so eines Elements ansprechen zu können. Aber: ich kann auf einen gewissen Basissatz aufsetzen, den alle graphicprimives mitbringen müssen. Sonst lassen sie sich (wegen der gewollten und erstrebenswerten) Typsicherheit erst garnicht in die Liste einfügen.

List(of objekt) brauchen nur sehr systemnahe Klassen. Für alles höhere ist das Schwachsinn.

(Firma: Jasinski) #7918800
Lesenswert?

Harald K. schrieb:

Ob S. schrieb:

Arrays bliebiger Element-Typen

... sind bei Programmieranfängern aus irgendeinem Grund sehr beliebt.

Was auch immer der Autor hier vorhat, es lässt sich in vb.NET mit sehr hoher Wahrscheinlichkeit ganz einfach lösen – ohne irgendwelche Array-Akrobatik, ohne Redimensionierung und sonstiges Ziehen oder Biegen – das Framework und die objektorientierte Programmierung bieten hierfür sehr viele Werkzeuge, man muss sie nur richtig auswählen und gebrauchen. Wenn man bestimmte Dinge nicht weiß oder kennt, macht man halt komische Sachen. Und die eigenen Datensätze sollte man schon ganz am Anfang kennen bzw. so festlegen, dass es passt und – falls nötig – auch jederzeit ohne komische Akrobatik erweiterbar ist, und nicht alles umgekehrt machen, sonst kommt nämlich genau das dabei raus, was man sich fabriziert hat.

Und wenn man es am Anfang mit den Datensätzen oder Datentypen so richtig verkackt hat, kann man am Ende trotzdem immer noch die Oberkeule 'Object' nehmen – in einer objektorientierten Umgebung ist das – wie der Name schon sagt – jederzeit möglich. Um an alle Daten zu gelangen, muss man dann halt einen Zusatzaufwand betreiben, aber selbst das würde in einer objektorietierten Umgebung problemlos funktionieren und wäre typsicher.

OP #7923029
Lesenswert?

Habe jetzt nun so gemacht:

1
    Public Sub AddToArray(Of T)(ByRef array() As T, ByVal item As T)
2
        If array Is Nothing Then
3
            array = New T() {item}
4
        Else
5
            Dim newArray() As T
6
            newArray = array
7
            ExpandArray(newArray)
8
            newArray(UBound(newArray)) = item
9
            array = newArray
10
        End If
11
    End Sub

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren