2013-06-12 1 views
6

Следующий код VB.NET работы:Почему мой код компилировать в VB.NET, но эквивалент в C# не удается

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) 

Следующий C# код не компилировать:

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

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

reportRequestService.SaveRequest(ref request); 

LearnerLogbookReportRequest объявлен как:

Public Class LearnerLogbookReportRequest 
    Inherits AbstractReportRequest 

Ошибка:

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 

Почему версия C# не удается скомпилировать?

ответ

12

VB довольно слабее с параметрами ByRef, чем у C#. Например, он позволяет передавать свойства по ссылке. C# не допускает этого.

Аналогичным образом, с Option Strict выключен, VB позволяет использовать аргумент, являющийся подтипом объявленного параметра. В короткой, но полной программе, подумайте:

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 

Это работает в VB, но эквивалент в C# не будет ... и по уважительной причине. Это опасно. В этом случае мы используем переменную строку и мы бываем изменить p ссылаться на другую строку, но если мы изменим тело Foo на:

p = new Object() 

Тогда мы получим исключение во время выполнения:

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

ref в основном это время компиляции типобезопасный в C#, но ByRef не типобезопасная в VB с Option Strict выключена.

Если добавить:

Option Strict On 

к программе в VB, однако (или просто изменить параметры по умолчанию для вашего проекта), вы должны увидеть те же проблемы в 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) 
      ~ 

Это наводит на мысль что вы в настоящее время кодируете без Option Strict ... Я бы рекомендовал использовать его как можно скорее.

+0

+1 - Я предложил на Meta новые плакаты к тегу VB.NET, чтобы проверить их опцию Strict Setting http://meta.stackexchange.com/questions/144007/inform-new-posters-tagging-vb -net-to-check-option-strict-setting, но он был отклонен. Я добавил примечание к тегу Wiki, но для чего его стоит. Этот параметр действительно должен быть включен по умолчанию. –

Смежные вопросы