2012-03-15 76 views
7

Tôi đến từ thế giới C# để VB.NET và câu đố này tôi. Tại sao có 2 cách để làm điều tương tự? hoặc có một số khác biệt mà tôi không biết?Sự khác nhau giữa thuộc tính và hàm được tham số trong vb.net là gì?

sự khác biệt giữa những điều sau là gì:

Public ReadOnly Property Test(ByVal v as String) As Integer 
    Get 
    Return SomeOperationOn(v) 
    End Get 
End Property 

Public Function Test(ByVal v as String) As Integer 
    Return SomeOperationOn(v) 
End Function 

Khi nào bạn sử dụng một như trái ngược với người kia?

Trả lời

10

Chức năng không có sự khác biệt, cả hai đều trả về giá trị dựa trên tham số. Trên thực tế, các thuộc tính thực sự được chuyển thành các hàm trong khi biên dịch, vì khái niệm về thuộc tính không tồn tại trong MSIL.

Semantically, tuy nhiên, có sự khác biệt về cách chúng nên được sử dụng. Thuộc tính có nghĩa là một cách để lộ trạng thái bên trong của một đối tượng. Mặt khác, chức năng được coi là hoạt động trên trạng thái của đối tượng hoặc cung cấp câu trả lời cho một câu hỏi cụ thể (truy vấn) hoặc sửa đổi trạng thái theo một cách nào đó (một lệnh ).

Dưới đây là một ví dụ:

Public Class Rectangle 
    Private _size As Size 

    ReadOnly Property Size() As Size 
     Get 
      Return _size 
     End Get 
    End Property 

    Public Function IsSquare() As Boolean 
     Return _size.Width = _size.Height 
    End Function 
End Class 

Trong khi Size đơn giản cho thấy một tài sản của đối tượng, các IsSquare chức năng thực sự thực hiện một hoạt động vào trạng thái nội bộ của đối tượng để trả lời một câu hỏi.

Dựa trên nguyên tắc này, các trường hợp sử dụng phổ biến nhất cho các thuộc tính tham số trong VB.NET là trong lớp học mà đại diện cho một chuỗi các mặt hàng, nơi mà các tham số được sử dụng để truy cập vào một yếu tố cụ thể trong chuỗi bởi vị thế của mình hoặc bởi một số khóa duy nhất. Nói cách khác, để tạo ra những gì được gọi là indexers trong C#.

5

Tại đây khách còn có thể có một setter:

Public Property Test(ByVal v as String) As Integer 
    Get 
     Return SomeDictionary(v) 
    End Get 
    Set 
     SomeDictionary(v) = Value 
    End Set 
End Property 

Điều đó làm cho một sự khác biệt, bởi vì nó cho phép bạn viết một cái gì đó như thế này:

MyObject.Test(index) = SomeValue 

C# chỉ cho phép bạn gán như thế qua người lập chỉ mục thuộc tính:

MyOjbect[index] = SomeValue; 

Điều đó có nghĩa trong C# bạn chỉ có thể có một thuộc tính được lập chỉ mục cho mỗi kiểu. VB.Net cho phép nhiều hơn một thuộc tính được lập chỉ mục trên một kiểu. Để có được cú pháp tương đương, C# sẽ phải hiển thị trực tiếp từ điển cơ bản hoặc nếu bạn có mã khác trong trình lấy/đặt (chẳng hạn như ghi nhật ký), bạn sẽ phải tạo một loại bổ sung để bọc từ điển của bạn.

+0

MyOjbect [index] = SomeValue; Bạn có thể thực hiện điều đó thông qua một thuộc tính mặc định trong vb.net – MarcelDevG

+0

Có, bạn có thể làm điều đó. Bạn chỉ có thể có một thuộc tính mặc định. Điều này cho phép bạn có nhiều thuộc tính giống như từ điển trên cùng một loại. –

+0

Ngữ nghĩa, nhưng bạn không thể có một setter trong thuộc tính 'ReadOnly'. –

10

Có rất nhiều lịch sử đằng sau câu hỏi này, điều này quay trở lại năm 1997 khi Microsoft phát hành đặc tả kỹ thuật tự động hóa COM. Cho phép các bộ định vị/getters được phép có đối số.Visual Basic là một người dùng đầu tiên của spec, nó đã được điều khiển trong phần nhỏ của ngôn ngữ để tìm một sự thay thế cho mô hình mở rộng VBX. Mà chạy ra khỏi khí xung quanh thời gian đó, nó đã phụ thuộc nhiều vào mô hình mã hóa 16-bit.

Nhóm C# lấy thái độ khá vô nghĩa đối với đối tượng địa lý, họ tuyệt đối ghét sự mơ hồ về cú pháp. Điều đó không thuộc về một ngôn ngữ hoàn toàn mới. VB.NET không có cùng một sự sang trọng, họ đã phải ít nhất hỗ trợ một số tính năng của thế hệ trước, VB6 vào thời điểm đó.

Tua lùi 10 năm, nhóm C# phải quay lại một chút do nhu cầu phổ biến. Các thuộc tính được lập chỉ mục là đầy đủ, ví dụ, mô hình đối tượng Office. Trong phiên bản C# 4, chúng cho phép các thuộc tính được lập chỉ mục dành riêng cho các giao diện COM để làm mềm bớt nỗi đau khi viết mã C# Office. Và nhiều hơn nữa, các đối số tùy chọn và được đặt tên cũng đã được thêm vào để xử lý sự đau khổ Type.Missing. Và từ khóa động để hỗ trợ ràng buộc trễ, một tính năng quan trọng khác của COM và Visual Basic là thực sự là gây khó khăn khi thực hiện trong C# mà không có từ khóa đó.

Ngắn câu chuyện ngắn, COM là đẹp, sự thanh lịch của IUnknown là tuyệt vời. Tony Williams là thiên tài đằng sau nó. Video is here, đáng xem. Các tập hợp con của COM Automation, IDispatch, không phải là quá đẹp. Nhưng nó cực kỳ thành công. Ngôn ngữ bỏ qua nó lúc nguy hiểm của họ. C# không.

Những chi tiết này có thể là âm thanh phức tạp từ một thời đại đã qua rồi nhưng không. Phiên bản tiếp theo của Windows API, WinRT hoàn toàn dựa trên IUnknown. Nếu không được gọi là "Metro" hoặc "Giao diện người dùng hiện đại". IDispatch không tồn tại, thay thế bằng IInspectable.

+0

Trong C#, cú pháp này sẽ không mơ hồ vì một chỉ mục mảng không giống như một cuộc gọi phương thức trong C# giống như trong VB. –

+0

@Joel - có bao nhiêu chỉ mục? Nhiều hơn một là việc gác máy thông thường. worksheet.Cells [x, y] được hỗ trợ trong C# phiên bản 4, đóng một thủ thuật khó chịu trên các lập trình viên cũng muốn gọi Marshal.ReleaseComObject(). Có một tham chiếu giao diện IRange ở đó là vô hình. –

+0

Tôi muốn các nhà thiết kế ngôn ngữ sẵn sàng chấp nhận các cấu trúc "mơ hồ" có thể được làm rõ với sự ràng buộc tham lam. Nếu 'Test [int]' là một thuộc tính được lập chỉ mục của lớp 'Foo' và' Test' là một thuộc tính bình thường, 'Foo.Text [3]' sẽ sử dụng thuộc tính 'Test' đã được lập chỉ mục của' Foo', trong khi ' (Foo.Text) [3] 'sẽ sử dụng thuộc tính không được lập chỉ mục' Kiểm tra', và sau đó truy cập thuộc tính được lập chỉ mục mặc định của nó. Không chỉ không có sự mơ hồ thực sự, nhưng đôi khi ý nghĩa của 'Foo.Text [3]' có thể rõ ràng, nhưng 'var blah = Foo.Text;' có thể không. Các thuộc tính được đặt tên cho phép mã để cho phép mã trước đó trong khi cấm sau này. – supercat

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