Reputation: 1714
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 fails to compile:
LearnerLogbookReportRequest request = new LearnerLogbookReportRequest();
request.LearnerIdentityID = theLearner.ID;
request.EntryVersion = LearnerLogbookEntryVersion.Full;
IReportRequestService reportRequestService = ServiceFactory.GetReportRequestService(ServiceInvoker.LearnerLogbook);
reportRequestService.SaveRequest(ref request);
The 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 is the C# version failing to compile?
Upvotes: 6
Views: 427
Reputation: 1500535
VB is rather looser with ByRef
parameters than C# is. For example, it allows you to pass properties by reference. C# doesn't allow this.
In a similar way, with Option Strict off, VB allows you to use an argument which is a subtype of the declared parameter. As a short but complete program, consider this:
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
That works in VB, but the equivalent in C# wouldn't... and for good reason. It's dangerous. In this case, we're using a string variable and we happen to 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 execution time:
Unhandled Exception: System.InvalidCastException: Conversion from type 'Object' to type 'String' is not valid.
Basically ref
is compile-time type-safe in C#, but ByRef
isn't type-safe in VB with Option Strict off.
If you add:
Option Strict On
to the program in VB, however (or just change the defaults 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're currently coding without Option Strict... I'd recommend using it ASAP.
Upvotes: 13