Freigeben über


Problembehandlungsverfahren (Visual Basic)

Auf dieser Seite sind einige häufige Probleme aufgeführt, die beim Arbeiten mit Prozeduren auftreten können.

Zurückgeben eines Arraytyps aus einer Funktionsprozedur

Wenn eine Function Prozedur einen Arraydatentyp zurückgibt, können Sie den Function Namen nicht verwenden, um Werte in den Elementen des Arrays zu speichern. Wenn Sie versuchen, dies zu tun, interpretiert der Compiler ihn als Aufruf der Function. Im folgenden Beispiel werden Compilerfehler generiert:

Function AllOnes(n As Integer) As Integer()
   For i As Integer = 1 To n - 1  
      ' The following statement generates a COMPILER ERROR.  
      AllOnes(i) = 1  
   Next  

   ' The following statement generates a COMPILER ERROR.  
   Return AllOnes()  
End Function

Die Anweisung AllOnes(i) = 1 generiert einen Compilerfehler, da er mit einem Argument des falschen Datentyps (einem Skalar Integer anstelle eines Integer Arrays) aufgerufen AllOnes wird. Die Anweisung Return AllOnes() generiert einen Compilerfehler, da er ohne Argument aufgerufen AllOnes wird.

Richtiger Ansatz: Um die Elemente eines Arrays zu ändern, das zurückgegeben werden soll, definieren Sie ein internes Array als lokale Variable. Im folgenden Beispiel wird ohne Fehler kompiliert:

Function AllOnes(n As Integer) As Integer()
    Dim iArray(n - 1) As Integer
    For i = 0 To n - 1
        iArray(i) = 1
    Next
    Return iArray
End Function

Argument nicht durch Prozeduraufruf geändert

Wenn Sie es einer Prozedur gestatten möchten, ein Programmierelement zu ändern, das einem Argument im aufrufenden Code zugrunde liegt, müssen Sie es per Verweis übergeben. Eine Prozedur kann jedoch auch dann auf die Elemente eines Bezugstyparguments zugreifen, wenn Sie sie nach Wert übergeben.

  • Zugrunde liegende Variable. Damit die Prozedur den Wert des zugrunde liegenden Variablenelements selbst ersetzen kann, muss die Prozedur den Parameter ByRef deklarieren. Außerdem darf der aufrufende Code das Argument nicht in Klammern einschließen, da dadurch der ByRef Übergabemechanismus überschreiben würde.

  • Referenztypelemente. Wenn Sie einen Parameter ByVal deklarieren, kann die Prozedur das zugrunde liegende Variablenelement nicht selbst ändern. Wenn das Argument jedoch ein Verweistyp ist, kann die Prozedur die Elemente des Objekts ändern, auf das es verweist, auch wenn er den Wert der Variablen nicht ersetzen kann. Wenn es sich bei dem Argument beispielsweise um eine Arrayvariable handelt, kann die Prozedur ihm kein neues Array zuweisen, aber es kann ein oder mehrere seiner Elemente ändern. Die geänderten Elemente werden in der zugrunde liegenden Arrayvariable im aufrufenden Code wiedergegeben.

Im folgenden Beispiel werden zwei Prozeduren definiert, die eine Arrayvariable nach Wert verwenden und mit ihren Elementen arbeiten. Die Prozedur increase fügt jedem Element einfach ein Element hinzu. Die Prozedur replace weist dem Parameter a() ein neues Array zu und fügt dann jedem Element ein Array hinzu. Die Neuzuweisung wirkt sich jedoch nicht auf die zugrunde liegende Arrayvariable im aufrufenden Code aus, da a() sie deklariert ByValwird.

Public Sub increase(ByVal a() As Long)
    For j As Integer = 0 To UBound(a)
        a(j) = a(j) + 1
    Next j
End Sub
Public Sub replace(ByVal a() As Long)
    Dim k() As Long = {100, 200, 300}
    a = k
    For j As Integer = 0 To UBound(a)
        a(j) = a(j) + 1
    Next j
End Sub

Im folgenden Beispiel werden Aufrufe an increase und replace:

Dim n() As Long = {10, 20, 30, 40}
Call increase(n)
MsgBox("After increase(n): " & CStr(n(0)) & ", " & 
    CStr(n(1)) & ", " & CStr(n(2)) & ", " & CStr(n(3)))
Call replace(n)
MsgBox("After replace(n): " & CStr(n(0)) & ", " & 
    CStr(n(1)) & ", " & CStr(n(2)) & ", " & CStr(n(3)))

Der erste MsgBox Aufruf zeigt "Nach Erhöhung(n): 11, 21, 31, 41" an. Da n es sich um einen Verweistyp handelt, increase können sie die Member ändern, auch wenn sie übergeben ByValwird.

Der zweite MsgBox Aufruf zeigt "After replace(n): 11, 21, 31, 41" an. Da n übergeben ByValwird, kann die Variable n nicht geändert werden, replace indem sie ihm ein neues Array zuweist. Wenn replace sie die neue Arrayinstanz k erstellt und der lokalen Variablen azugewiesen wird, verliert sie den Verweis, n der vom aufrufenden Code übergeben werden soll. Wenn die Elemente aerhöht werden, ist nur das lokale Array k betroffen.

Richtiger Ansatz: Um ein zugrunde liegendes Variablenelement selbst ändern zu können, übergeben Sie es per Verweis. Das folgende Beispiel zeigt die Änderung in der Deklaration replace , die es ermöglicht, ein Array durch ein anderes im aufrufenden Code zu ersetzen:

Public Sub replace(ByRef a() As Long)

Eine Überladung kann nicht definiert werden.

Wenn Sie eine überladene Version einer Prozedur definieren möchten, müssen Sie denselben Namen, aber eine andere Signatur verwenden. Wenn der Compiler ihre Deklaration nicht von einer Überladung mit derselben Signatur unterscheiden kann, wird ein Fehler generiert.

Die Signatur einer Prozedur wird durch den Prozedurnamen und die Parameterliste bestimmt. Jede Überladung muss denselben Namen wie alle anderen Überladungen haben, muss jedoch von allen in mindestens einer der anderen Komponenten der Signatur abweichen. Weitere Informationen finden Sie unter Prozedurüberladung.

Die folgenden Elemente, auch wenn sie sich auf die Parameterliste beziehen, sind keine Komponenten der Signatur einer Prozedur:

  • Schlüsselwörter für Prozedurmodifizierer, z Public. B. , Shared, und Static.
  • Parameternamen.
  • Parametermodifiziererstichwörter, z ByRef . B. und Optional.
  • Der Datentyp des Rückgabewerts (mit Ausnahme eines Konvertierungsoperators).

Sie können eine Prozedur nicht überladen, indem Sie nur eines oder mehrere der vorherigen Elemente variieren.

Richtiger Ansatz: Um eine Prozedurüberladung definieren zu können, müssen Sie die Signatur variieren. Da Sie denselben Namen verwenden müssen, müssen Sie die Anzahl, Reihenfolge oder Datentypen der Parameter variieren. In einer generischen Prozedur können Sie die Anzahl der Typparameter variieren. In einem Konvertierungsoperator (CType-Operator) können Sie den Rückgabetyp variieren.

Überladungsauflösung mit optionalen und ParamArray-Argumenten

Wenn Sie eine Prozedur mit einem oder mehreren optionalen Parametern oder einem ParamArray-Parameter überladen, müssen Sie eine der impliziten Überladungen vermeiden. Weitere Informationen finden Sie unter Überlegungen in überladenen Prozeduren.

Aufrufen der falschen Version einer überladenen Prozedur

Wenn eine Prozedur über mehrere überladene Versionen verfügt, sollten Sie mit allen parameterlisten vertraut sein und verstehen, wie Visual Basic Aufrufe zwischen den Überladungen löst. Andernfalls könnten Sie eine andere Überladung als die beabsichtigte aufrufen.

Wenn Sie festgestellt haben, welche Überladung Sie aufrufen möchten, achten Sie darauf, die folgenden Regeln zu beachten:

  • Geben Sie die richtige Anzahl von Argumenten und in der richtigen Reihenfolge an.
  • Im Idealfall sollten Ihre Argumente genau die gleichen Datentypen wie die entsprechenden Parameter aufweisen. In jedem Fall muss der Datentyp jedes Arguments auf den entsprechenden Parameter ausgedehnt werden. Dies gilt auch bei festgelegter Option Strict-AnweisungOff. Wenn eine Überladung eine schmale Konvertierung aus Der Argumentliste erfordert, kann diese Überladung nicht aufgerufen werden.
  • Wenn Sie Argumente angeben, die eine Erweiterung erfordern, stellen Sie deren Datentypen so nah wie möglich an die entsprechenden Parameterdatentypen fest. Wenn zwei oder mehr Überladungen Die Argumentdatentypen akzeptieren, löst der Compiler den Aufruf der Überladung auf, die für die geringste Verbreiterung aufruft.

Sie können die Wahrscheinlichkeit von Datentypkonflikten verringern, indem Sie das Schlüsselwort für die Konvertierung der CType-Funktion beim Vorbereiten der Argumente verwenden.

Fehler bei der Überladungsauflösung

Wenn Sie eine überladene Prozedur aufrufen, versucht der Compiler, alle außer einer der Überladungen zu beseitigen. Wenn er erfolgreich ist, wird der Aufruf dieser Überladung aufgelöst. Wenn alle Überladungen beseitigt werden, oder wenn sie die berechtigten Überladungen nicht auf einen einzelnen Kandidaten reduzieren kann, wird ein Fehler generiert.

Im folgenden Beispiel wird der Überlastungsauflösungsprozess veranschaulicht:

Overloads Sub z(ByVal x As Byte, ByVal y As Double)
End Sub
Overloads Sub z(ByVal x As Short, ByVal y As Single)
End Sub
Overloads Sub z(ByVal x As Integer, ByVal y As Single)
End Sub
Dim r, s As Short
Call z(r, s)
Dim p As Byte, q As Short
' The following statement causes an overload resolution error.
Call z(p, q)

Im ersten Aufruf beseitigt der Compiler die erste Überladung, da sich der Typ des ersten Arguments (Short) auf den Typ des entsprechenden Parameters (Byte) beschränkt. Anschließend wird die dritte Überladung entfernt, da jeder Argumenttyp in der zweiten Überladung (Short und Single) auf den entsprechenden Typ in der dritten ÜberladungInteger ( und Single). Die zweite Überladung erfordert eine geringere Erweiterung, sodass der Compiler sie für den Aufruf verwendet.

Im zweiten Aufruf kann der Compiler keine Überladungen aufgrund der Verengung beseitigen. Sie beseitigt die dritte Überladung aus demselben Grund wie im ersten Aufruf, da sie die zweite Überladung mit weniger Verbreiterung der Argumenttypen aufrufen kann. Der Compiler kann jedoch nicht zwischen den ersten und zweiten Überladungen aufgelöst werden. Jeder hat einen definierten Parametertyp, der sich auf den entsprechenden Typ in der anderen (ByteShortbis , aber Single auf Double) erweitert. Der Compiler generiert daher einen Überladungsauflösungsfehler.

Richtiger Ansatz: Um eine überladene Prozedur ohne Mehrdeutigkeit aufrufen zu können, verwenden Sie die CType-Funktion , um die Argumentdatentypen den Parametertypen zuzuordnen. Das folgende Beispiel zeigt einen Aufruf, der z die Auflösung für die zweite Überladung erzwingt.

Call z(CType(p, Short), CType(q, Single))

Überladungsauflösung mit optionalen und ParamArray-Argumenten

Wenn zwei Überladungen einer Prozedur identische Signaturen aufweisen, mit der Ausnahme, dass der letzte Parameter in einem und ParamArray in der anderen deklariert wird, löst der Compiler einen Aufruf dieser Prozedur entsprechend der nächstgelegenen Übereinstimmung auf. Weitere Informationen finden Sie unter Überladungsauflösung.

Siehe auch