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