2013-06-12 5 views
6

Das folgende VB.NET-Code funktioniert:Warum mein Code nicht kompiliert in VB.NET aber das Äquivalent in C# nicht

Dim request As Model.LearnerLogbookReportRequest = New Model.LearnerLogbookReportRequest 
request.LearnerIdentityID = Convert.ToInt32(Session("identityID")) 
request.EntryVersion = LearnerLogbookEntryVersion.Full 

Dim reportRequestService As IReportRequestService = ServiceFactory.GetReportRequestService(ServiceInvoker.LearnerLogbook) 
     reportRequestservice.SaveRequest(request) 

Der folgende C# -Code nicht kompilieren:

LearnerLogbookReportRequest request = new LearnerLogbookReportRequest(); 
request.LearnerIdentityID = theLearner.ID; 
request.EntryVersion = LearnerLogbookEntryVersion.Full; 

IReportRequestService reportRequestService = ServiceFactory.GetReportRequestService(ServiceInvoker.LearnerLogbook); 

reportRequestService.SaveRequest(ref request); 

Die LearnerLogbookReportRequest wird erklärt, wie:

Public Class LearnerLogbookReportRequest 
    Inherits AbstractReportRequest 

Fehler:

Error 11 Argument 1: cannot convert from 'ref RACQ.ReportService.Common.Model.LearnerLogbookReportRequest' to 'ref RACQ.ReportService.Common.Model.AbstractReportRequest' C:\p4projects\WEB_DEVELOPMENT\SECURE_ASPX\main-dev-codelines\LogbookSolution-DR6535\RACQ.Logbook.Web\Restful\SendLogbook.cs 64 50 RACQ.Logbook.Web 

Warum kann die C# -Version nicht kompiliert werden?

Antwort

12

VB ist eher loser mit ByRef Parameter als C# ist. Zum Beispiel können Sie Eigenschaften als Referenz übergeben. C# lässt dies nicht zu.

Auf ähnliche Weise können Sie mit VB Option Strict off ein Argument verwenden, das ein Untertyp des deklarierten Parameters ist. Als kurze, aber vollständige Programm, bedenken Sie:

Imports System 

Public Class Test 
    Public Shared Sub Main(args As String()) 
     Dim p As String = "Original" 
     Foo(p) 
     Console.WriteLine(p) 
    End Sub 

    Public Shared Sub Foo(ByRef p As Object) 
     p = "Changed" 
    End Sub 
End Class 

Das in VB funktioniert, aber das Äquivalent in C# würde nicht ... und das aus gutem Grund. Es ist gefährlich. In diesem Fall verwenden wir ein String-Variable und wir passieren p zu ändern, um eine andere Zeichenfolge zu verweisen, aber wenn wir den Körper von Foo zu ändern:

p = new Object() 

Dann haben wir Zeit bekommen, eine Ausnahme bei der Ausführung:

Unhandled Exception: System.InvalidCastException: Conversion from type 'Object' to type 'String' is not valid.

Grundsätzlich ref ist Compiler-typsicher in C#, aber ByRef ist nicht typsicher in VB mit Option Strict aus.

Wenn Sie hinzufügen:

Option Strict On 

auf das Programm in VB, aber (oder nur die Standardeinstellungen für Ihr Projekt aus) Sie das gleiche Problem in VB sehen sollte:

error BC32029: Option Strict On disallows narrowing from type 'Object' to type 
'String' in copying the value of 'ByRef' parameter 'p' back to the matching 
argument. 

     Foo(p) 
      ~ 

Dies legt nahe, dass Sie derzeit ohne Option Strict programmieren ... Ich würde empfehlen, es so schnell wie möglich zu verwenden.

+0

+1 - Ich schlug auf Meta vor, dass neue Plakate zum VB.NET-Tag vorgeschlagen werden, um ihre Option Strict Setting zu überprüfen http://meta.stackexchange.com/questions/144007/inform-new-posters-tagging-vb -net-to-check-option-strict-setting, aber es wurde abgelehnt. Ich habe dem Tag-Wiki jedoch eine Notiz hinzugefügt, was es wert ist. Diese Einstellung sollte standardmäßig aktiviert sein. –

Verwandte Themen