2010-03-25 27 views
20

Khi chúng tôi có new trong C#, cá nhân tôi chỉ xem như một giải pháp để ghi đè thuộc tính không có khai báo ảo/có thể ghi đè, trong VB.NET, chúng tôi có hai "khái niệm" ShadowsOverloads.Shadows vs Overloads trong VB.NET

Trong trường hợp này, cái này thích cái khác?

Trả lời

13

Có ba khái niệm có liên quan chặt chẽ; ghi đè, đổ bóng và quá tải.

Ghi đè là khi bạn thực hiện triển khai mới cho phương pháp ảo.

Làm mờ là khi bạn thực hiện triển khai không ảo mới cho một phương pháp.

Quá tải là khi bạn thêm phương thức có cùng tên nhưng thông số khác nhau.

Tất cả ba khái niệm đều có sẵn cả trong C# và VB.

+1

Câu hỏi không phải là về trọng, điều này là OK. Bây giờ ** Quá tải ** cũng có thể được sử dụng để ** bóng ** thành viên hiện có, hoặc tập hợp các thành viên quá tải, trong một lớp cơ sở. Khi bạn sử dụng quá tải theo cách này, bạn khai báo thuộc tính hoặc phương thức có cùng tên và cùng một danh sách đối số làm thành viên lớp cơ sở và bạn không cung cấp từ khóa Shadows. Tôi thấy * new * (C#) = * Shadows * (VB.NET), C# tương đương với quá tải là gì? – serhio

+0

@serhio: Tôi vừa đề cập đến việc ghi lại sự hoàn chỉnh vì đó là khái niệm có liên quan chặt chẽ. Vì từ khóa Overloads trong VB cũng có thể được sử dụng để làm bóng, không có tương đương chính xác trong C#. Trong C# không có từ khóa cho quá tải, bạn chỉ cần khai báo một phương thức có cùng tên và chữ ký khác để quá tải nó. – Guffa

+1

vì vậy, định nghĩa của bạn chưa hoàn thành, do đó, 2 khái niệm này vẫn chưa rõ ràng cho tôi. 'Shadows' tạo ra một hàm" mới "và' Overloads' là (có thể) được sử dụng cho cùng một phạm vi. vậy sự khác biệt là gì. – serhio

0

Shadows là dành cho các trường hợp lớp cơ sở của bạn là Function SomeMethod() As String và bạn muốn có Function SomeMethod() As Integer. Về cơ bản, để thay đổi kiểu trả về.

Overloads là trường hợp lớp cơ sở của bạn là Function SomeMethod() As String và bạn muốn thêm thông số như Function SomeMethod(ByVal value As Integer) As String.

+2

** Quá tải ** cũng có thể được sử dụng để ** Bóng ** thành viên hiện có hoặc tập hợp các thành viên bị quá tải, trong một lớp cơ sở. Khi bạn sử dụng quá tải theo cách này, bạn khai báo thuộc tính hoặc phương thức có cùng tên và cùng một danh sách đối số làm thành viên lớp cơ sở và bạn không cung cấp từ khóa Shadows. – serhio

16

Tôi thực sự xác nhận bằng cách biên dịch cùng mã với Shadows so với Overloads cho phương thức có tên và chữ ký giống hệt nhau trong lớp cơ sở và xem kết quả từ ildasm cho cả hai. Sự khác biệt duy nhất là trường hợp Overloads chỉ định hidebysig.

Tầm quan trọng của điều này là tốt nhất được giải thích bởi Jon Skeet trong this answer.

Nhưng chỉ đơn giản là nó có nghĩa là chỉ có một sự khác biệt thực sự nếu các lớp cơ sở có quá tải của phương pháp này được xác định lại:

  • Shadows sẽ gây tất cả những quá tải là uncallable qua lớp được thừa kế , trong đó có
  • Overloads chỉ thay thế phương thức một.

Lưu ý rằng đây chỉ là ngôn ngữ được xây dựng và không được thi hành bởi CLI (tức là C# và VB.NET thi hành điều này nhưng các ngôn ngữ khác có thể không).

Một đơn giản mã ví dụ:

Module Module1 

Sub Main() 
    Dim a1 As C1 = New C2 
    Dim a2 As New C2 
    a1.M1() 
    a2.M1() 
    a1.M2() 
    a2.M2() 
    a1.M3() 
    a2.M3() 

    a1.M1(1) 
    ' Overloads on M1() allows the M1(int) to be inherited/called. 
    a2.M1(1) 
    a1.M2(1) 
    ' Shadows on M2() does not allow M2(int) to be called. 
    'a2.M2(1) 
    a1.M3(1) 
    ' Shadows on M3() does not allow M3(int) to be called, even though it is Overridable. 
    'a2.M3(1) 

    If Debugger.IsAttached Then _ 
     Console.ReadLine() 
End Sub 

End Module 

Class C1 
Public Sub M1() 
    Console.WriteLine("C1.M1") 
End Sub 
Public Sub M1(ByVal i As Integer) 
    Console.WriteLine("C1.M1(int)") 
End Sub 
Public Sub M2() 
    Console.WriteLine("C1.M2") 
End Sub 
Public Sub M2(ByVal i As Integer) 
    Console.WriteLine("C1.M2(int)") 
End Sub 
Public Overridable Sub M3() 
    Console.WriteLine("C1.M3") 
End Sub 
Public Overridable Sub M3(ByVal i As Integer) 
    Console.WriteLine("C1.M3(int)") 
End Sub 
End Class 

Class C2 
Inherits C1 
Public Overloads Sub M1() 
    Console.WriteLine("C2.M1") 
End Sub 
Public Shadows Sub M2() 
    Console.WriteLine("C2.M2") 
End Sub 
Public Shadows Sub M3() 
    Console.WriteLine("C2.M3") 
End Sub 
' At compile time the different errors below show the variation. 
' (Note these errors are the same irrespective of the ordering of the C2 methods.) 
' Error: 'Public Overrides Sub M1(i As Integer)' cannot override 'Public Sub M1(i As Integer)' because it is not declared 'Overridable'. 
'Public Overrides Sub M1(ByVal i As Integer) 
' Console.WriteLine("C2.M1(int)") 
'End Sub 
' Errors: sub 'M3' cannot be declared 'Overrides' because it does not override a sub in a base class. 
'   sub 'M3' must be declared 'Shadows' because another member with this name is declared 'Shadows'. 
'Public Overrides Sub M3(ByVal i As Integer) 
' Console.WriteLine("C2.M3(int)") 
'End Sub 
End Class 

Đầu ra của trên:

C1.M1 
C2.M1 
C1.M2 
C2.M2 
C1.M3 
C2.M3 
C1.M1(int) 
C1.M1(int) 
C1.M2(int) 
C1.M3(int) 

Kết quả cho thấy Shadows cuộc gọi được sử dụng khi C2 được gọi là trực tiếp và không phải khi gọi là gián tiếp thông qua C1.