Unterschied zwischen Dim x() As String und Dim x As String()

  • VB.NET

Es gibt 30 Antworten in diesem Thema. Der letzte Beitrag () ist von Marcus Gräfe.

    Unterschied zwischen Dim x() As String und Dim x As String()

    Gibt es irgendeinen Unterschied zwischen Dim x() As String und Dim x As String()? Man beachte die Position der Klammern.
    Besucht auch mein anderes Forum:
    Das Amateurfilm-Forum
    Danke für den Link.

    So ganz verstanden habe ich es allerdings nicht. Unter VB6 gab es nur Variante 1, das mit den Klammern hinter dem Datentyp ist mir und in VB.NET neu.

    Niko Ortner schrieb:

    Die Array-Deklaration mit den Klammern beim Variablenname sollte man nicht verwenden.

    OK, das kann ich mir schon mal merken, vernünftiges .NET-Programmieren macht man scheinbar mit den Array-Klammern hinter dem Datentyp.

    Aber nicht nachvollziehen kann ich den Grund:

    Niko Ortner schrieb:

    Private _Value() As Integer 'Welchen Typ hat das Feld?

    Für mich als VB6-Entwickler ist das völlig klar: Es ist ein Integer-Array. Geht es jetzt also nur um die Verständlichkeit/Lesbarkeit?
    Besucht auch mein anderes Forum:
    Das Amateurfilm-Forum
    @Marcus Gräfe Das ist in VB.NET egal, in C# müssen die Klammern nachg string stehen: string[] x.
    Ansonsten setz nen Haltepunkt drauf und sieh Dir den Inhalt an. ;)
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Naja, wenn ich lese

    VB.NET-Quellcode

    1. Dim Test() As Integer
    dann denk ich mir beim flüchtigen Drüberschauen, dass hier eine einfache Integervariable deklariert wird.
    Bei

    VB.NET-Quellcode

    1. Dim Test As Integer()
    seh ich sofort: Test ist ein (Typangabe:) Integer-Array.

    Leider macht es Mikrosaft aus meiner Sicht kontraintuitiv. Gibt man einer noch nicht geschriebenen Prozedur ein Array an die Hand und lässt den Prozedurrumpf automatisch erstellen, dann kommt raus:

    VB.NET-Quellcode

    1. Private Sub Foo()
    2. Dim TestArray As Integer() = {}
    3. TestProcedure(TestArray)
    4. End Sub
    5. Private Sub TestProcedure(testArray() As Integer)
    6. Throw New NotImplementedException()
    7. End Sub

    Klammern leider hinter dem Namen, nicht hinter dem Datentyp.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Danke euch.

    Ich habe es nun so verstanden, dass es technisch keinerlei Unterschied gibt, aber die Klammern hinter dem Typ besser lesbar, logischer und mehr wie C# sind, was dafür spricht, es so zu machen anstatt wie zu VB6-Zeiten.
    Besucht auch mein anderes Forum:
    Das Amateurfilm-Forum

    Marcus Gräfe schrieb:

    Für mich als VB6-Entwickler ist das völlig klar: Es ist ein Integer-Array.

    Richtig.
    Aber sieh dir die Property an, die direkt darunter steht. Sie ist mit der gleichen Syntax geschrieben. Also möchte man meinen, dass der Typ auch ein Integer-Array ist.
    Um es mit den Worten von Herbert Grönemeyer auszudrücken: Isses aber nicht.
    Denn Properties können Parameter haben:

    VB.NET-Quellcode

    1. Private _Value() As Integer 'Welchen Typ hat das Feld?
    2. Public ReadOnly Property Value(Index As Integer) As Integer 'Welchen Typ hat die Property?
    3. Get
    4. Return _Value(Index)
    5. End Get
    6. End Property

    Es wäre komisch, wenn das bloße Hinzufügen eines Index zur Property plötzlich den Typ von Integer-Array auf Integer ändern würde.


    Der Konzeptuelle Unterschied ist der:
    Bei C deklarierst du mit int x[10]; quasi "10 Variablen vom Typ int". Dort, wo du die Variable hinschreibst, liegen tatsächlich auch die 10 ints.
    In VB sieht Dim x(10 - 1) As Integer auch so aus, ist aber äquivalent zu Dim X As Integer() = New Integer(10 - 1) {}. Da, wo du x hinschreibst, liegen also nicht die 10 Integer, sondern eine Referenz auf einen Speicherbereich, der das eigentliche Array it. Das Konzept, 10 Variablen vom Typ Integer zu deklarieren, ist hier also nicht gegeben. Und um diese Verwirrung zu vermeiden, sollte man die Schreibweise mit den Klammern beim Namen nicht verwenden.

    Also ja, es geht um die Lesbarkeit.
    "Luckily luh... luckily it wasn't poi-"
    -- Brady in Wonderland, 23. Februar 2015, 1:56
    Desktop Pinner | ApplicationSettings | OnUtils
    Sorry, aber ist das nicht i-Tüpflerei ?

    Ob Dim x() As String und Dim x As String() ist ja wirklich egal. Jeder so wie er/sie das besser lesen kann.

    Ich persönlich komme von VB und könnte mit der zweiten Variante nichts anfangen weil ich die erste Variante gewohnt bin - ich würde die Klammern einfach überlesen.
    Ein C-Programmierer würde mit der zweiten Variante möglicherweise was anfangen - aber der wird höchstwahrscheinlich sowieso in C programmieren und nicht in VB :thumbup: .

    Aber dennoch interessant zu wissen, dass es auch diese Variante (die zweite) gibt. Wenn beide das selbe machen, ist es aber wirklich egal welche man nimmt.

    Schlussendlich ist nur wirklich das wichtig was man daraus macht - eine g´scheite Anwendung ;)
    Liebe Grüße
    Roland Berghöfer

    Meine aktuellen und kostenlos verwendbaren Tools (mit VB.NET erstellt): freeremarkabletools.com | priconman.com | SimpleCalendar | AudibleTouch | BOComponent.com | bonit.at

    ErfinderDesRades schrieb:

    man kann allerdings das Array auch gleich dimensionieren

    Das ist mir natürlich bewusst. Ich programmiere seit 20 Jahren mit VB6. ;)

    Niko Ortner schrieb:

    Denn Properties können Parameter haben

    Das wusste ich gar nicht. Unter VB6 war das noch nicht so (denke ich). Ich habe auch noch nie eine Eigenschaft mit Parameter gesehen. Wird mir wohl irgendwann mal über den Weg laufen.

    Niko Ortner schrieb:

    sollte man die Schreibweise mit den Klammern beim Namen nicht verwenden

    Wird gemacht! :)

    Danke!
    Besucht auch mein anderes Forum:
    Das Amateurfilm-Forum

    dive26 schrieb:

    Sorry, aber ist das nicht i-Tüpflerei ?

    Naja, ich finde, es ist schon wichtig, diesen Unterschied im Konzept zu kennen. Besonders wenn man als Anfänger noch nicht so gut weiß, wie Objekte und Arrays und Variablen und das alles zusammenspielen, finde ich es gut, wenn die Syntax einheitlich und nicht verwirrend ist.
    Und es gibt wie gesagt sehr viele Ausnahmen von dieser Syntax. Bzw. müsste man sagen, dass diese Syntax die Ausnahme ist:
    Funktionen, die ein Integer-Array zurückgeben, kann man auch nicht mit Function Foo() As Integer deklarieren.
    Dim x(10 - 1) As Integer : Console.WriteLine(x.GetType.Name) gibt Int32[] aus, also mit Klammern beim Typ.
    Will man bei Dim f As Form eine Instanziierung draus machen, schreibt man Dim f As New Form oder Dim f = New Form, also es ein New vor den Typ zu schreiben, gibt dir eine neue Instanz des Typs. Will man das gleiche bei Dim x() As Integer machen, wäre das Äquivalent Dim x() As New Integer. New Integer wäre in jeder anderen Situation kein Integer-Array, sondern ein einzelner Integer. (Der Compiler erlaubt diese Syntax übrigens explizit nicht. Arrays können nicht mit "New" deklariert werden.. Wahrscheinlich, weil es zu verwirrend wäre.) Und hier noch was Ungünstiges: Dim x(10 - 1) As Integer versteckt das New, was aber ein entscheidendes Schlüsselwort ist.
    Also es gibt nur bei primitiven Sprachelementen (Feldern, Parametern und lokalen Variablen) diese Syntax. Alles, was mehr ist (Eigenschaften und Funktionen, und auch einfach alles, wo der Typ nicht in Verbindung mit einem Namen steht), erfordert die Klammern beim Typenname.

    Marcus Gräfe schrieb:

    Ich habe auch noch nie eine Eigenschaft mit Parameter gesehen.

    Unter der Haube vielleicht schon. Immer, wenn du eine List(Of T) hast, und davon per Index auf ein Item zugreifst, verwendest du die Item-Property, die den Index als Parameter entgegennimmt. (Sie ist übrigens als Default deklariert, also wenn du DeineListe(0) hinschreibst, ist das Äquivalent zu DeineListe.Item(0).)
    "Luckily luh... luckily it wasn't poi-"
    -- Brady in Wonderland, 23. Februar 2015, 1:56
    Desktop Pinner | ApplicationSettings | OnUtils

    Marcus Gräfe schrieb:

    Das ist mir natürlich bewusst.
    Uh - das ist eine gefährliche Schein-Selbstverständlichkeit, auch nur in irgendeinem Detail von vb6 auf vb.net zu schliessen.
    Haut in diesem Falle ausnahmsweise hin, obwohls eiglich idiotisch ist.
    Weil der Datentyp eines Integer-Arrays heisst Integer(), und nicht anders.
    Die vb6-Schreibe ist daher völlig unlogisch:

    VB.NET-Quellcode

    1. dim x(9) As Integer
    Da steht klippnklar: As Integer - und das ist falsch!
    Weil x ist hier ein Integer(), und kein Integer - das ist ein Unterschied wie zwischen Praline und Pralinen-Schachtel.

    Aber der vb-Compiler versteht das so, und der sitzt letztlich am längeren Hebel.

    ErfinderDesRades schrieb:

    Aber der vb-Compiler versteht das so, und der sitzt letztlich am längeren Hebel.
    Das ist das Problem, dass VB so wenig restriktiv ist, wohl, um .NET Anfängern schmackhaft zu machen.
    Da bin ich lieber bei C#.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    In C/C++ ist es übrigens die erste Variante.

    C-Quellcode

    1. int a[] = {0, 0};
    2. int b[2] = {};
    3. int c[3] = {};
    4. const bool ab_equal = std::is_same<decltype(a), decltype(b)>::value; // = true
    5. const bool bc_equal = std::is_same<decltype(b), decltype(c)>::value; // = false
    6. auto a_type = typeid(a).name(); // = int[2]

    Hier ist sogar int[2] ein anderer Typ als int[3]. Man deklariert also int a[] hinter dem Variablennamen, aber der Typ ist nicht int sondern int[]. Warum das so ist k.A., aber es ermöglicht Inlinedeklarationen int a, b[2], c[3];.
    Das ist das Problem, dass VB so wenig restriktiv ist, wohl, um .NET Anfängern schmackhaft zu machen.
    Da bin ich lieber bei C#.


    Warum wollt Ihr unbedingt alles kompliziert machen, wenn es doch auch einfach geht?
    Ich für meinen Teil nutze Funktionen die mir zur Verfügung gestellt werden ;) .

    Diejenigen denen VB zu einfach und zu wenig restriktiv ist, die programmieren ja ohnehin in C#. Wir VB-ler lieben das "wenig restriktive" :P
    Liebe Grüße
    Roland Berghöfer

    Meine aktuellen und kostenlos verwendbaren Tools (mit VB.NET erstellt): freeremarkabletools.com | priconman.com | SimpleCalendar | AudibleTouch | BOComponent.com | bonit.at

    dive26 schrieb:

    Wir VB-ler lieben das "wenig restriktive"
    Ich zähle mich einfach mal nicht dazu ;) , bleibe aber trotzdem bei VB.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Dito.

    Ich mag die VB-Syntax mehr als C#, weshalb ich mich durchaus als VBler betrachte.
    Und ich mag Restriktionen, weil sie üblicherweise für saubere Programmierung sorgen.

    Im diskutierten Fall von Dim x(3) As Integer haben wir zweifache Funktionalität:
    1) Instanziiere x als (leeres) Integer-Array
    2) Dimensioniere x von 0 bis 3
    Also gleichbedeutend mit

    VB.NET-Quellcode

    1. Dim x As Integer()
    2. ReDim x(3)


    Aber wenn ich ehrlich bin, habe ich unter VB.Net eh noch nie freiwillig mit Arrays gearbeitet.
    Schließlich gibt es da wesentlich mächtigere Möglichkeiten im Framework.
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --

    ErfinderDesRades schrieb:

    Uh - das ist eine gefährliche Schein-Selbstverständlichkeit

    Dann habe ich deinen Post wohl missverstanden ("man kann allerdings das Array auch gleich dimensionieren"). Ich dachte, du wolltest mir erzählen, dass man die Dimensionen eines Arrays auch schon bei der Deklaration festlegen kann. Und das ist nun wirklich logisch! Mir fällt nämlich keine Sprache ein, wo das nicht geht.

    ErfinderDesRades schrieb:

    Die vb6-Schreibe ist daher völlig unlogisch:

    Aber warum schreibst du sie dann in deinem Post? ;)
    Besucht auch mein anderes Forum:
    Das Amateurfilm-Forum
    Weils nunmal so ist.
    Das ist die gültige Syntax, und die ist unlogisch, aber nunmal gültig.
    Und funktioniert, und braucht man ja auch.

    (Es gibt übrigens noch eine weitere Möglichkeit, ein Array zu erzeugen, mit Shared Array.CreateInstance(), das ist zwar logisch aber so verquast und umständlich - dass die unlogische Variante immer noch den besser verständlichen Code ergibt.)

    Gonger96 schrieb:

    Warum das so ist k.A.,
    Siehe:

    Niko Ortner schrieb:

    Bei C deklarierst du mit int x[10]; quasi "10 Variablen vom Typ int".



    @Marcus Gräfe
    Um die Verwirrung zu vervollständigen: Es gibt auch die Syntax Dim x(0 To 9) As Integer bzw. Dim x = New Integer(0 To 9) {}. Also 0 bis 9 sind die gültigen Indices. x.UpperBound ist 9 und x.LowerBound ist 0.
    Jetzt denkt man sich vielleicht: "Kann LowerBound auch was anderes außer 0 sein?"
    "Well, yes, but actually no." Dim x(4 To 9) As Integer meckert der Compiler an: Untere Arraybegrenzung kann nur "0" sein. Die CLR könnte das krasserweise aber: Dim a As Array = Array.CreateInstance(GetType(Integer), {6}, {4}). Das ist aber schon nicht mehr trivial verwendbar. Ich hätte mir vorstellen können, um mit Krams zusammenzuarbeiten, bei dem Array-Indices bei 1 anfangen, wäre es praktisch gewesen, aber DirectCast(a, Integer()) löst eine InvalidCastException aus: Das Objekt des Typs "System.Int32[*]" kann nicht in Typ "System.Int32[]" umgewandelt werden. Man muss umständlich mit a.GetValue und a.SetValue arbeiten und damit ist das eigentlich ziemlich unsinnig.

    Marcus Gräfe schrieb:

    Mir fällt nämlich keine Sprache ein, wo das nicht geht.

    Ich schon: C# :P
    int x[10]; wäre eine Größenangabe bei der Deklaration. Ist in C# nicht erlaubt, weil's eben nicht das Gleiche wie in C und C++ bedeutet.
    Außer!
    Man verwendet unsafe: unsafe struct Foo { public fixed int x[10]; } bedeutet dann wirklich das Gleiche wie in C und C++!


    Ich mag das. Ich könnte mich stundenlang über solche Details unterhalten :D
    "Luckily luh... luckily it wasn't poi-"
    -- Brady in Wonderland, 23. Februar 2015, 1:56
    Desktop Pinner | ApplicationSettings | OnUtils