Condividi tramite


Modifiche importanti in Visual Basic 2008

Aggiornamento: Luglio 2008

Nella tabella seguente vengono elencate tutte le modifiche che potrebbero impedire la compilazione in Visual Studio 2008 di un'applicazione creata in Visual Studio 2005 o che potrebbero modificare il comportamento in fase di esecuzione.

Category

Problema

Descrizione

Tipi nullable

La conversione verso un tipo di dati più grande da T a T? è una caratteristica predefinita di Visual Studio 2008.

In Visual Studio 2005, è possibile creare una conversione definita dall'utente per consentire a T di passare al tipo di dati più grande Nullable(Of T). Questa conversione è un'impostazione predefinita che fa parte del maggiore supporto per i tipi nullable di Visual Studio 2008.

Dal momento che la risoluzione dell'overload considera sia le conversioni predefinite, sia quelle definite dall'utente, nel caso in cui siano presenti entrambe è possibile riscontrare un'ambiguità. Pertanto, il codice contenente una conversione verso un tipo di dati più grande da T a T? definita dall'utente è potenzialmente ambiguo in Visual Studio 2008.

Ad esempio, nel codice seguente, la chiamata all'oggetto c3.Sub1 funziona in Visual Studio 2005, ma provoca un errore del compilatore in Visual Studio 2008.

Module Module1
Sub Main()
Dim c3 As New Class3
Dim sh As Short = 2
' The following statement compiles in Visual Studio 2005,
' but causes an error in Visual Studio 2008.
'c3.Sub1(sh)
End Sub
End Module
Class Class1
Public Shared Widening Operator CType(ByVal s As _
Nullable(Of Short)) As Class1
Return New Class1()
End Operator
End Class
Class Class2
Public Shared Widening Operator CType(ByVal n As Integer) As Class2
Return New Class2()
End Operator
End Class
Class Class3
Sub Sub1(ByVal c As Class1)
End Sub
Sub Sub1(ByVal c As Class2)
End Sub
End Class

Per risolvere questo problema, è possibile rimuovere la conversione definita dall'utente oppure eseguire il cast in modo esplicito all'oggetto Class1 o Class2:

c3.Sub1(CType(sh, Class1))

Risoluzione dell'overload

Le differenze della risoluzione dell'overload tra classi generiche e non generiche sono state corrette.

Un bug in Visual Studio 2005 può causare una differenza di comportamento della risoluzione dell'overload tra le classi generiche e quelle non generiche. Nell'esempio seguente, gli oggetti Class1 e Class2 sono identici, tranne che l'oggetto Class2 dispone di un parametro generico definito. La chiamata all'oggetto c1.Sub1 in Main è ambigua poiché l'argomento passato ha potuto eseguire l'associazione a entrambi gli overload dell'oggetto Sub1 in Class1. L'ambiguità causa un errore del compilatore sia in Visual Studio 2005, sia in Visual Studio 2008.

La chiamata all'oggetto c2.Sub1 dovrebbe generare lo stesso errore, ma questa condizione non si verifica in Visual Studio 2005. Il metodo esegue infatti l'associazione all'overload senza vincoli dell'oggetto Sub1 in Class2.

Questo problema è stato risolto in Visual Studio 2008. Entrambe le chiamate generano errori del compilatore a causa dell'ambiguità. Questi processi vengono illustrati nel codice seguente:

Module Module1
Sub Main()
Dim c1 As New Class1
Dim c2 As New Class2(Of String)
' The following statement causes a compiler error in both
' Visual Studio 2005 and Visual Studio 2008.
'c1.Sub1(New Nullable(Of Integer))
' The following statement causes a compiler error only
' in Visual Studio 2008.
'c2.Sub1(New Nullable(Of Integer))
End Sub
End Module
Class Class1
Sub Sub1(Of T)(ByVal arg As T)
Console.WriteLine("Unconstrained Sub1 in Class1")
End Sub
Sub Sub1(Of T As Structure)(ByVal arg As Nullable(Of T))
Console.WriteLine("Constrained Sub1 in Class1")
End Sub
End Class
Class Class2(Of U)
Sub Sub1(Of T)(ByVal arg As T)
Console.WriteLine("Unconstrained Sub1 in Class2")
End Sub
Sub Sub1(Of T As Structure)(ByVal arg As Nullable(Of T))
Console.WriteLine("Constrained Sub1 in Class2")
End Sub
End Class

Per risolvere questo problema, è possibile modificare gli overload in modo che non siano più ambigui oppure specificare in modo esplicito gli argomenti di tipo:

c1.Sub1(Of Integer?)(New Nullable(Of Integer))
c2.Sub1(Of Integer?)(New Nullable(Of Integer))

Risoluzione dell'overload

La risoluzione dell'overload con parametri generici e ParamArray genera risultati diversi in Visual Studio 2008.

L'obiettivo della risoluzione dell'overload è la selezione del metodo candidato i cui parametri sono i più simili ai tipi di argomenti passati al metodo. Nell'esempio di questa sezione, l'oggetto Sub1 viene sottoposto a overload in una gerarchia di ereditarietà e chiamato con argomenti di tipo Integer e Short.

Le regole della risoluzione dell'overload di Visual Studio 2005 e di Visual Studio 2008 specificano che le corrispondenze dirette sono migliori rispetto a quelle che richiedono parametri ParamArray. Tuttavia, se si utilizzano le regole della risoluzione dell'overload di Visual Studio 2005, l'inferenza dei tipi non viene completata per il candidato dell'overload nella classe derivata, Class2, perché Y non può essere sia un oggetto Integer, sia un oggetto Short e, inoltre, vengono richieste corrispondenze esatte. Se gli argomenti sh e n fossero dello stesso tipo, l'oggetto Sub1 in Class2 verrebbe scelto di preferenza rispetto al candidato dell'oggetto Class1 che dispone di un parametro ParamArray. Tuttavia, dal momento che i due argomenti dispongono di tipi diversi, viene selezionato l'overload della classe base in Class1. L'oggetto T viene dedotto come Integer e l'oggetto Short viene convertito verso un tipo di dati più grande in ParamArrayp.

In Visual Studio 2008 viene utilizzato un nuovo algoritmo che consente di selezionare gli stessi overload di Visual Studio 2005, tranne in questo caso specifico. In Visual Studio 2008, l'algoritmo determina che l'oggetto Integer è il tipo dominante in questo esempio, poiché l'oggetto Short viene convertito verso il tipo di dati più grande Integer. Si deduce che il parametro di tipo Y della classe derivata sia Integer e l'oggetto Short viene convertito nel tipo di dati più grande Integer. Di conseguenza, viene chiamato l'oggetto Sub1 della classe derivata.

Module Module1
Sub Main()
Dim c2 As New Class2
Dim n As Integer
Dim sh As Short
c2.Sub1(n, sh)
End Sub
Class Class1
Sub Sub1(Of T)(ByVal arg1 As T, ByVal ParamArray p() As Integer)
Console.WriteLine("Visual Studio 2005 calls Sub1 " & _
"in the *base* class.")
End Sub
End Class
Class Class2 : Inherits Class1
Overloads Sub Sub1(Of Y)(ByVal arg1 As Y, ByVal arg2 As Y)
Console.WriteLine("Visual Studio 2008 calls Sub1 " & _
"in the *derived* class.")
End Sub
End Class
End Module

È possibile forzare il comportamento di Visual Studio 2005 eseguendo il cast della variabile c2 al tipo C1ass1 prima di chiamare l'oggetto Sub1 o passando l'argomento sh come matrice.

' You can cast variable c2 to Class1 in order to force Visual
' Studio 2005 behavior.
CType(c2, Class1).Sub1(n, sh)
' Alternatively, you can pass sh as an array.
c2.Sub1(n, New Integer() {sh})

Vedere anche

Concetti

Risoluzione dell'overload

Tipi di valori nullable

Tipi generici in Visual Basic

Riferimenti

ParamArray

Cronologia delle modifiche

Data

Cronologia

Motivo

Luglio 2008

Argomento aggiunto.

Miglioramento delle informazioni.