6

以下 VB.NET 代码有效:

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# 版本无法编译?

4

1 回答 1

13

ByRefVB 在参数方面比 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()

然后我们在执行时得到一个异常:

未处理的异常:System.InvalidCastException:从“对象”类型到“字符串”类型的转换无效。

在 C# 中基本上ref是编译时类型安全的,但ByRef在禁用 Option Strict 的 VB 中不是类型安全的。

如果添加:

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 的代码……我建议您尽快使用它。

于 2013-06-12T05:30:45.877 回答