2013-06-12 38 views
6

Mã VB.NET sau hoạt động:Tại sao mã của tôi biên dịch trong VB.NET nhưng tương đương trong C# không

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) 

Mã C# sau thất bại trong việc biên dịch:

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

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

reportRequestService.SaveRequest(ref request); 

Các LearnerLogbookReportRequest được khai báo là:

Public Class LearnerLogbookReportRequest 
    Inherits AbstractReportRequest 

Lỗi:

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 

Tại sao phiên bản C# không biên dịch được?

Trả lời

12

VB khá lỏng lẻo với thông số ByRef so với C#. Ví dụ, nó cho phép bạn vượt qua các thuộc tính bằng cách tham chiếu. C# không cho phép điều này.

Tương tự, với Option Strict tắt, VB cho phép bạn sử dụng đối số là một loại phụ của tham số được khai báo. Là một chương trình ngắn nhưng đầy đủ, hãy xem xét điều này:

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 

Hoạt động trong VB, nhưng tương đương trong C# sẽ không ... và vì lý do chính đáng. Nguy hiểm. Trong trường hợp này, chúng tôi đang sử dụng một biến chuỗi và chúng tôi xảy ra để thay đổi p để đề cập đến một chuỗi khác, nhưng nếu chúng ta thay đổi cơ thể của Foo tới:

p = new Object() 

Sau đó chúng ta có được một ngoại lệ tại thời gian thực hiện:

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

Về cơ bản ref là thời gian biên dịch kiểu an trong C#, nhưng ByRef không được gõ-an toàn trong VB với Option Strict tắt.

Nếu bạn thêm:

Option Strict On 

để chương trình trong VB, tuy nhiên (hoặc chỉ cần thay đổi giá trị mặc định cho dự án của bạn), bạn sẽ thấy cùng một vấn đề trong 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) 
      ~ 

Điều này cho thấy rằng bạn hiện đang mã hóa mà không có Tùy chọn Nghiêm ngặt ... Tôi khuyên bạn nên sử dụng nó càng sớm càng tốt.

+0

+1 - Tôi đã đề xuất trên Meta rằng các áp phích mới cho thẻ VB.NET được đề xuất để kiểm tra Cài đặt tùy chọn nghiêm ngặt của chúng http://meta.stackexchange.com/questions/144007/inform-new-posters-tagging-vb -net-to-check-option-strict-setting nhưng nó đã được bình chọn. Tuy nhiên, tôi đã thêm ghi chú vào Tag Wiki cho giá trị của nó. Cài đặt này thực sự phải được bật theo mặc định. –

Các vấn đề liên quan