共用方式為


成員多載

更新:2007 年 11 月

成員的簽章包括它的名稱和參數清單;每一個成員簽章在型別中都必須是唯一的。成員可以有相同的名稱,只要其參數清單不同即可。當某個型別中的兩個或多個成員為相同類型的成員 (方法、屬性、建構函式等),而且有相同的名稱和不同的參數清單,則該成員就可以多載。例如,Array 類別包含兩個 CopyTo 方法;第一個方法可接受陣列和 Int32 值,而第二個方法則可接受陣列和 Int64 值。

注意事項:

變更方法的傳回型別並不會如 Common Language Runtime 規格中所陳述一樣,讓此方法變成唯一。您無法定義只有傳回型別不同的多載。

多載成員應該在相同功能上提供一些變化。例如,某型別如果有兩個 CopyTo 成員,就是不正確的 (第一個成員將資料複製到陣列,第二個成員將資料複製到檔案)。成員多載的常用方式是提供可接受少數或零個參數且容易使用的多載。這些成員會呼叫比較有威力的多載,但是如果要正確使用,也需要更多的經驗。容易使用的多載可藉由將預設值傳遞給複雜多載來支援一般狀況。例如,File 類別可為 Open 方法提供多載。簡單的多載 Open 可接受檔案路徑和檔案模式,它會呼叫 Open 多載,此多載可接受路徑、檔案模式、檔案存取及檔案共用等參數,並針對檔案存取和檔案共用參數提供常用的預設值。不需要複雜多載的彈性之開發人員,不必要在開啟檔案之前了解檔案存取和共用的模型。

為了要便於維護及進行版本控制,較簡單的多載應該使用複雜多載來執行其動作;基礎功能不應該在多個地方實作。

多載化方針

下列方針可協助您確保多載成員有經過良好的設計。

要嘗試使用描述性參數名稱來指示較簡單的多載所用的預設值。

這個方針最適用於 Boolean 參數。較複雜的多載之參數名稱應該指示較簡單的多載所提供的預設值,透過的方式是描述相反的狀態或動作。例如,String 類別可提供下列多載:

Overloads Public Shared Function Compare( _
   ByVal strA As String, _
   ByVal strB As String _
) As Integer

Overloads Public Shared Function Compare( _
   ByVal strA As String, _
   ByVal strB As String, _
   ByVal ignoreCase As Boolean _
) As Integer
public static int Compare(
   string strA,
   string strB
);

public static int Compare(
   string strA,
   string strB,
   bool ignoreCase
);

第二個多載會提供名為 ignoreCase 的 Boolean 參數,這表示較簡單的多載會區分大小寫,而且只有在您想要忽略大小寫時,才需要使用較複雜的多載。一般來說,預設值通常應該是 false。

避免在多載中任意改變參數名稱。如果一個多載中的參數代表與另一個多載中的參數相同的輸入,則這些參數應該有相同名稱。

例如,請勿執行下列作業:

Public Sub Write(message as String, stream as FileStream)
End Sub
Public Sub Write(line as String, file as FileStream, closeStream as Boolean)
End Sub
public void Write(string message, FileStream stream){}
public void Write(string line, FileStream file, bool closeStream){}

這些多載的正確定義如下:

Public Sub Write(message as String, stream as FileStream)
End Sub
Public Sub Write(message as String, stream as FileStream, _
    closeStream as Boolean)
End Sub
public void Write(string message, FileStream stream){}
public void Write(string message, FileStream stream, bool closeStream){}

在多載成員中排序參數時,務必要一致。具有相同名稱的參數應該出現在所有多載中的相同位置。

例如,請勿執行下列作業:

Public Sub Write( message as String, stream as FileStream)
End Sub
Public Sub Write(stream as FileStream, message as String, _
    closeStream as Boolean)
End Sub
public void Write(string message, FileStream stream){}
public void Write(FileStream stream,  string message, bool closeStream){}

這些多載的正確定義如下:

Public Sub Write(message as String, stream as FileStream)
End Sub
Public Sub Write(message as String, stream as FileStream, _
    closeStream as Boolean)
End Sub
public void Write(string message, FileStream stream){}
public void Write(string message, FileStream stream, bool closeStream){}

這個方針有兩個條件約束:

  • 如果多載接受變數引數清單,該清單必須是最後一個參數。

  • 如果多載接受 out 參數,則依照慣例,這些參數應該以最後的參數之形式出現。

如果需要擴充性,只需將最長的多載變成虛擬 (Visual Basic 中為 Overridable)。較短的多載只應該呼叫較長的多載。

下列程式碼範例將示範這個作法。

Public Sub Write(message as String, stream as FileStream)
    Me.Write(message, stream, false)
End Sub

Public Overridable Sub Write( _
    message as String, stream as FileStream, closeStream as Boolean)
    ' Do work here.
End Sub
public void Write(string message, FileStream stream)
{
    this.Write(message, stream, false);
}
public virtual void Write(string message, FileStream stream, bool closeStream)
{
    // Do work here.
}

請勿使用 ref 或 out 修飾詞來多載成員。

例如,請勿執行下列作業。

Public Sub Write(message as String,  count as Integer)


...


Public Sub Write(message as String, ByRef count as Integer)
public void Write(string message, int count)


...


public void Write(string message, out int count)

一般來說,如果您的設計發生了這個情況,很有可能有更深層的設計問題。請考量其中一個成員是否應該重新命名,才能提供與此方法採取的動作之相關資訊。

允許為選擇性引數傳遞 null (Visual Basic 中為 Nothing)。如果方法接受參考型別做為選擇性引數,請允許傳遞 null,以指示應該使用預設值。如此可避免必須在呼叫成員之前檢查是否為 null 的問題。

例如,開發人員在下列範例中應該不需要檢查是否為 null。

Public Sub CopyFile (source as FileInfo, _
    destination as DirectoryInfo, _
    newName as string)

    If newName Is Nothing
        InternalCopyFile(source, destination) 
    Else
        InternalCopyFile(source, destination, newName)
    End If
End Sub
public void CopyFile (FileInfo source, DirectoryInfo destination, string newName)
{
    if (newName == null)
    {
        InternalCopyFile(source, destination);
    }
    else
    {
        InternalCopyFile(source, destination, newName);
    }
}

要使用成員多載,而不要以預設引數定義成員。預設引數不符合 CLS 標準,而且不能在某些語言中使用。

下列程式碼範例將示範錯誤的方法設計。

Public Sub Rotate (data as Matrix, Optional degrees as Integer = 180)
' Do rotation here
End Sub

此程式碼應該重新設計為兩個多載,其中較簡單的多載要提供預設值。下列程式碼範例將示範正確的設計。

Overloads Public Sub Rotate (data as Matrix)
    Rotate(data, 180)
End Sub

Overloads Public Sub Rotate (data as Matrix, degrees as Integer)
' Do rotation here
End Sub

Portions Copyright 2005 Microsoft Corporation.All rights reserved.

Portions Copyright Addison-Wesley Corporation.All rights reserved.

如需設計方針的詳細資訊,請參閱由 Krzysztof Cwalina 和 Brad Abrams 所著,並由 Addison-Wesley 於 2005 年發行的「Framework 設計方針:可重複使用之 .NET 程式庫的慣例、慣用語法和模式」一書。

請參閱

其他資源

成員設計方針

開發類別庫的設計方針