Forum: PC-Programmierung Funktion "AddToArray" in vb.net


von Ate E. (drigo)


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?

von Harald K. (kirnbichler)


Lesenswert?

Früher gab es in VB den Datentyp "Variant", da konnte man alles 
reinstopfen. Kann das das .Net-Geraffel nicht?

von Ate E. (drigo)


Lesenswert?

Harald K. schrieb:
> Früher gab es in VB den Datentyp "Variant", da konnte man alles
> reinstopfen. Kann das das .Net-Geraffel nicht?

Habe doch geschrieben, dass es VB.net ist!

von Heinz B. (Firma: Privat) (hbrill)


Lesenswert?

Ich kenne mich zwar VB.Net nicht so aus, deshalb habe ich mal gegoogelt.
Sollte da nicht overloads helfen ? Damit kann man doch mehrere 
Prozeduren
gleichen Namens, aber mit verschiedenen Parametern definieren.

https://learn.microsoft.com/de-de/dotnet/visual-basic/programming-guide/language-features/procedures/procedure-overloading

von Gregor J. (Firma: Jasinski) (gregor_jasinski)


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 & ", "

: Bearbeitet durch User
von Ob S. (Firma: 1984now) (observer)


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.
1
Public Class ExpandebleArray(Of T)
2
    Private a As T()
3
4
    Public ReadOnly Property BaseArray As T()
5
        Get
6
            Return a
7
        End Get
8
    End Property
9
    Public ReadOnly Property Length As Integer
10
        Get
11
            Return a.Length
12
        End Get
13
    End Property
14
    Default Public Property Item(Index As Integer) As T
15
        Get
16
            Return a(Index)
17
        End Get
18
        Set(value As T)
19
            a(Index) = value
20
        End Set
21
    End Property
22
23
    Public Sub Append(NewElement As T)
24
        ReDim Preserve a(a.Length)
25
        a(a.Length - 1) = NewElement
26
    End Sub
27
28
    Public Sub New(InitialLastElementIndex As Integer)
29
        a = New T(InitialLastElementIndex) {}
30
    End Sub
31
32
End Class

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.

von Gregor J. (Firma: Jasinski) (gregor_jasinski)


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.

: Bearbeitet durch User
von Peter M. (r2d3)


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!

von Ob S. (Firma: 1984now) (observer)


Lesenswert?

Ob S. schrieb:

>
1
> Public Class ExpandebleArray(Of T)
2
> ...
3
>

Ich hatte noch vergessen, die Verwendung für dein Beispiel aufzuzeigen:
1
public Countries as new ExpandebleArray(of CountryStruct)(-1)
2
3
...
4
5
dim NewCountry as new CountryStruct
6
NewCountry.Name = "SeppelLand"
7
Countries.Append(NewCountry)
8
9
Print Countries(0).Name

von Ob S. (Firma: 1984now) (observer)


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.

von Gregor J. (Firma: Jasinski) (gregor_jasinski)


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.

: Bearbeitet durch User
von Ob S. (Firma: 1984now) (observer)


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...

von Gregor J. (Firma: Jasinski) (gregor_jasinski)


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.

: Bearbeitet durch User
von Ob S. (Firma: 1984now) (observer)


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.

von Harald K. (kirnbichler)


Lesenswert?

Ob S. schrieb:
> Arrays bliebiger Element-Typen

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

von Gregor J. (Firma: Jasinski) (gregor_jasinski)


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.

: Bearbeitet durch User
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.