Benutzer mit den meisten Antworten
Option Strict On Late Binding

Frage
-
Hallo zusammen,
kann mir jemand sagen, wie das auszusehen hat, wenn Option Strict On und Late Binding verwenden möchte
Dim xlWorkbook As Object = Nothing
Dim xlApp As Object = Nothing
xlWorkbook = xlApp.Workbooks.Open(FileName)
Oder ich habe z.B. in einem Loop
IF row.Item(sH, DataRowVersion.Original) <> row.Item(sH, DataRowVersion.Current) ThenMuss ich auf Option Strict On ganz verzichten, oder gibt es da irgendeine Deklarationsmöglichkeit?
Gruss Peter
Antworten
-
Hallo Peter,
für jemand laut eigener Aussage "bequem ist" (O-Ton), produzierst Du einen Haufen Mist für nichts.
Die von Dir reklamierte Unabhängigkeit ist eine Illusion. Passen die Schnittstellen wegen einer Änderung nicht, so wird es scheppern. Du hast eigentlich nur Glück, dass (zumindest bei Office) auf solche Leichtsinn Rücksicht genommen wird.
Notwendig ist das Ganze mit .NET 4.0 nicht mehr, siehe dazu Exemplarische Vorgehensweise: Einbetten von Typinformationen aus Microsoft Office-Assemblys (C# und Visual Basic) und Du darfst Deiner Bequemlichkeit zumindest dabei fröhnen ;)
Allerdings beim zweiten solltest Du wieder aufstehen, denn
IF row.Item(sH, DataRowVersion.Original) <> row.Item(sH, DataRowVersion.Current) Then
produziert zwar bei Option Strict Off keinen (Compiler-) Fehler aber trotzdem Schrott. Ein kleines Beispiel mit (D)einer falschen und mehreren "richtigeren" Lösungen:
Dim table As New DataTable() table.Columns.Add("Id", GetType(Integer)) table.Columns.Add("Name", GetType(String)) Dim rows() = New DataRow() { table.Rows.Add(1, "ABC"), table.Rows.Add(2, Nothing), table.Rows.Add(3, "DEF"), table.Rows.Add(4, Nothing)} table.AcceptChanges() rows(0)("Name") = "abc" rows(1)("Name") = "ABC" rows(2)("Name") = Nothing rows(3)("Id") = DBNull.Value rows(3)("Name") = DBNull.Value For Each row As DataRow In table.Rows ' Nur Option Strict Off und fehlerhaft bei Nullwerten 'If row("Name", DataRowVersion.Current) <> row("Name", DataRowVersion.Original) Then ' funktioniert wegen Überladung von Equals bei integrierten (richtig implementierten) Typen If Not row("Name", DataRowVersion.Current).Equals(row("Name", DataRowVersion.Original)) Then ' DataSetExentions, konvertiert DbNull zu Nothing (Null) 'If row.Field(Of String)("Name", DataRowVersion.Current) <> row.Field(Of String)("Name", DataRowVersion.Original) Then ' Für Werttypen wie Integer; Richtig in C#, Visual Basic ist leider mal wieder zu schlau 'If row.Field(Of Integer?)("Id", DataRowVersion.Current) <> row.Field(Of Integer?)("Id", DataRowVersion.Original) Then ' nur so geht es auch in VB richtig (siehe oben) 'If Not row.Field(Of Integer?)("Id", DataRowVersion.Current).Equals(row.Field(Of Integer?)("Id", DataRowVersion.Original)) Then Console.WriteLine("{0}: {1} ungleich", DirectCast(row("Id", DataRowVersion.Original), Object), row("Name")) Else Console.WriteLine("{0}: {1} gleich", row("Id", DataRowVersion.Original), row("Name")) End If Next
Die Geschichte mit den DataSetExtensions ist eines der Beispiele, wo die Visual Basic Erbauer am Ziel vorbei geschossen sind, und verbessern wollten, wo es nichts zu verbessern gab...
Abschließend gesagt, liefert Option Strict Off in den wenigsten Fällen "bessere" Ergebnisse, kann (und wird) aber jede Menge Probleme verursachen. Ich habe es von Anfang an (ab VB 2002) gemieden und bin in einer anderen Sprache (C#), die es lange (vor dynamic) gar nicht konnte, ebenso gut, oft sogar besser zurecht gekommen (weil der Compiler seltener schlau sein will). Dass Visual Basic die notwendigen Anweisungen abschreckend lang gestaltet - wie DirectCast(o, Typname) -, sollte kein Grund sein, darauf zu verzichten.
Gruß Elmar
- Als Antwort markiert peter haus Freitag, 27. März 2015 11:32
Alle Antworten
-
Hallo,
Option Strict besagt eigentlich nur, dass alles worauf zugegriffen wird, mit 100%iger Sicherheit vorhanden sein muss.So sollte man beispielsweise nichts als Object deklarieren, weil man dann eben wirklich nur auf die Member von Object zugreifen kann. Dein Code sieht nach Office/Excel InterOp aus, da müsste die Deklaration in etwa so aussehen:
Dim xlWorkbook As Excel.Workbook = Nothing Dim xlApp As Excel.Application = Nothing xlWorkbook = xlApp.Workbooks.Open(FileName)
Ein ähnliches Problem wird auch bei deiner if-Abfrage vorliegen. row o.ä. ist als Typ einfach Object zugeordnet.
Grundsätzlich kannst du alles mit Option Strict On machen, was auch ohne geht.
Tom Lambert - .NET (C#) MVP
Wozu Antworten markieren und für Beiträge abstimmen? Klicke hier.
Nützliche Links: .NET Quellcode | C# ↔ VB.NET Konverter | Account bestätigen (Verify Your Account)
Ich: Webseite | Code Beispiele | Facebook | Twitter | Snippets -
Hallo Tom,
>Option Strict besagt eigentlich nur, dass alles worauf zugegriffen wird, mit 100%iger Sicherheit vorhanden sein muss.
Hast du da etwas mit Option Explicit verwechselt ??Ich möchte bei Excel unabhängig von der installierten Version sein.
Deswegen möchte ich auf ein
Imports Microsoft.Office.Interop verzichten.Gruss Peter
-
Hallo,
IMHO bringt es nichts auf den Import des Namespaces zu verzichten. .NET Assemblies funktionieren nur dann, wenn sie alle nötigen Verweise finden. Die Deklaration einer Variable eines bestimmten Typs hat damit nichts zu tun.Tom Lambert - .NET (C#) MVP
Wozu Antworten markieren und für Beiträge abstimmen? Klicke hier.
Nützliche Links: .NET Quellcode | C# ↔ VB.NET Konverter | Account bestätigen (Verify Your Account)
Ich: Webseite | Code Beispiele | Facebook | Twitter | Snippets -
Hallo
das ganze sieht am Ende so aus.
Und ich bin unabhängig von der installierten Version.Am Ende der Entwicklung setze ich ComInterOp=0, es funktioniert so!
Imports Microsoft.Office.Interop
- - -
#If ComInterOp = 1 Then
Dim xlApp As Excel.Application = Nothing
Dim xlWorkbook As Excel._Workbook = Nothing
Dim xlWorksheet As Excel._Worksheet
Dim exRange As Excel.Range
#Else
Dim xlApp As Object = Nothing
Dim xlWorkbook As Object = Nothing
Dim xlWorksheet As object
Dim exRange As object
#End If
Try
#If ComInterOp = 1 Then
xlApp = New Excel.Application
#Else
xlApp=CreateObject("Excel.Application")
#End IfxlWorkbook = xlApp.Workbooks.Open(FileName)
#If ComInterOp = 1 Then
xlWorksheet = CType(xlWorkbook.Sheets.Item(1), Excel.Worksheet)
Dim xlRange As Excel.Range = xlWorksheet.UsedRange
#Else
xlWorksheet = xlWorkbook.Sheets.Item(1)
Dim xlRange As Object
xlRange = xlWorksheet.UsedRange
#End IfDim ColMax = xlWorksheet.UsedRange.Columns.Count
Dim MaxRows = xlWorksheet.UsedRange.Rows.Count- - -
-
Hallo Peter,
für jemand laut eigener Aussage "bequem ist" (O-Ton), produzierst Du einen Haufen Mist für nichts.
Die von Dir reklamierte Unabhängigkeit ist eine Illusion. Passen die Schnittstellen wegen einer Änderung nicht, so wird es scheppern. Du hast eigentlich nur Glück, dass (zumindest bei Office) auf solche Leichtsinn Rücksicht genommen wird.
Notwendig ist das Ganze mit .NET 4.0 nicht mehr, siehe dazu Exemplarische Vorgehensweise: Einbetten von Typinformationen aus Microsoft Office-Assemblys (C# und Visual Basic) und Du darfst Deiner Bequemlichkeit zumindest dabei fröhnen ;)
Allerdings beim zweiten solltest Du wieder aufstehen, denn
IF row.Item(sH, DataRowVersion.Original) <> row.Item(sH, DataRowVersion.Current) Then
produziert zwar bei Option Strict Off keinen (Compiler-) Fehler aber trotzdem Schrott. Ein kleines Beispiel mit (D)einer falschen und mehreren "richtigeren" Lösungen:
Dim table As New DataTable() table.Columns.Add("Id", GetType(Integer)) table.Columns.Add("Name", GetType(String)) Dim rows() = New DataRow() { table.Rows.Add(1, "ABC"), table.Rows.Add(2, Nothing), table.Rows.Add(3, "DEF"), table.Rows.Add(4, Nothing)} table.AcceptChanges() rows(0)("Name") = "abc" rows(1)("Name") = "ABC" rows(2)("Name") = Nothing rows(3)("Id") = DBNull.Value rows(3)("Name") = DBNull.Value For Each row As DataRow In table.Rows ' Nur Option Strict Off und fehlerhaft bei Nullwerten 'If row("Name", DataRowVersion.Current) <> row("Name", DataRowVersion.Original) Then ' funktioniert wegen Überladung von Equals bei integrierten (richtig implementierten) Typen If Not row("Name", DataRowVersion.Current).Equals(row("Name", DataRowVersion.Original)) Then ' DataSetExentions, konvertiert DbNull zu Nothing (Null) 'If row.Field(Of String)("Name", DataRowVersion.Current) <> row.Field(Of String)("Name", DataRowVersion.Original) Then ' Für Werttypen wie Integer; Richtig in C#, Visual Basic ist leider mal wieder zu schlau 'If row.Field(Of Integer?)("Id", DataRowVersion.Current) <> row.Field(Of Integer?)("Id", DataRowVersion.Original) Then ' nur so geht es auch in VB richtig (siehe oben) 'If Not row.Field(Of Integer?)("Id", DataRowVersion.Current).Equals(row.Field(Of Integer?)("Id", DataRowVersion.Original)) Then Console.WriteLine("{0}: {1} ungleich", DirectCast(row("Id", DataRowVersion.Original), Object), row("Name")) Else Console.WriteLine("{0}: {1} gleich", row("Id", DataRowVersion.Original), row("Name")) End If Next
Die Geschichte mit den DataSetExtensions ist eines der Beispiele, wo die Visual Basic Erbauer am Ziel vorbei geschossen sind, und verbessern wollten, wo es nichts zu verbessern gab...
Abschließend gesagt, liefert Option Strict Off in den wenigsten Fällen "bessere" Ergebnisse, kann (und wird) aber jede Menge Probleme verursachen. Ich habe es von Anfang an (ab VB 2002) gemieden und bin in einer anderen Sprache (C#), die es lange (vor dynamic) gar nicht konnte, ebenso gut, oft sogar besser zurecht gekommen (weil der Compiler seltener schlau sein will). Dass Visual Basic die notwendigen Anweisungen abschreckend lang gestaltet - wie DirectCast(o, Typname) -, sollte kein Grund sein, darauf zu verzichten.
Gruß Elmar
- Als Antwort markiert peter haus Freitag, 27. März 2015 11:32