【问题标题】:Why does my code compile in VB.NET but the equivalent in C# fails为什么我的代码在 VB.NET 中编译但在 C# 中的等效代码失败
【发布时间】:2013-06-08 03:13:53
【问题描述】:

以下 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#版本编译失败?

【问题讨论】:

    标签: c# vb.net .net-2.0 vb.net-to-c#


    【解决方案1】:

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

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

    未处理的异常:System.InvalidCastException:从“Object”类型到“String”类型的转换无效。

    基本上ref 在 C# 中是编译时类型安全的,但 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 的代码...我建议尽快使用它。

    【讨论】:

    • +1 - 我在 Meta 上建议建议 VB.NET 标签的新海报检查他们的选项严格设置 meta.stackexchange.com/questions/144007/… 但它被否决了。我在 Tag Wiki 中添加了一条注释,但它的价值。这个设置真的应该默认开启。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-22
    • 1970-01-01
    • 2020-08-09
    • 1970-01-01
    相关资源
    最近更新 更多