Why is my code compiling in VB.NET, but the equivalent in C # does not work

The following VB.NET code works:

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) 

The following C # code will not compile:

 LearnerLogbookReportRequest request = new LearnerLogbookReportRequest(); request.LearnerIdentityID = theLearner.ID; request.EntryVersion = LearnerLogbookEntryVersion.Full; IReportRequestService reportRequestService = ServiceFactory.GetReportRequestService(ServiceInvoker.LearnerLogbook); reportRequestService.SaveRequest(ref request); 

LearnerLogbookReportRequest is declared as:

 Public Class LearnerLogbookReportRequest Inherits AbstractReportRequest 

Error:

 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 

Why can't compile a C # version?

+6
source share
1 answer

VB is rather weaker with ByRef parameters than C #. For example, it allows you to pass properties by reference. C # does not allow this.

Similarly, with Option Strict turned off, VB allows you to use an argument, which is a subtype of the declared parameter. As a short but complete program, consider the following:

 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 

This works in VB, but the equivalent in C # is not ... and not in vain. This is dangerous. In this case, we use a string variable, and we can change p to refer to another string, but if we change the body of Foo to:

 p = new Object() 

Then we get an exception at runtime:

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

Basically ref is safe for compile time in C #, but ByRef not type safe in VB with the Strict off option.

If you add:

 Option Strict On 

for a program in VB (or just changing the default values ​​for your project), you should see the same problem in VB:

 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) ~ 

This suggests that you are currently coding without Option Strict ... I would recommend using it as soon as possible.

+12
source

Source: https://habr.com/ru/post/947075/


All Articles