멤버 오버로드
멤버의 시그니처에는 해당 이름 및 매개 변수 목록이 포함됩니다. 각 멤버 시그니처는 형식에서 고유해야 합니다. 해당 매개 변수 목록이 다른 경우 여러 멤버가 동일한 이름을 사용할 수 있습니다. 한 형식에서 두 개 이상의 멤버가 유형이 같고 즉, 동일한 메서드, 속성, 생성자 등이고 이름이 같으며 매개 변수 목록은 다른 경우 해당 멤버를 오버로드된 멤버라고 합니다. 예를 들어, Array 클래스에는 두 개의 CopyTo 메서드가 포함됩니다. 첫 번째 메서드는 배열과 Int32 값을 사용하고 두 번째 메서드는 배열과 Int64 값을 사용합니다.
참고 |
---|
메서드의 반환 형식을 변경하여 해당 메서드를 공용 언어 런타임 사양에 명기된 대로 고유하게 만들 수는 없습니다.반환 형식만으로는 다양한 오버로드를 정의할 수 없습니다. |
오버로드된 멤버는 동일한 기능에 대한 변형을 제공해야 합니다. 예를 들어, 하나의 형식이 두 개의 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:
void Write(String^ message, FileStream^ stream){}
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:
void Write(String^ message, FileStream^ stream){}
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:
void Write(String^ message, FileStream^ stream){}
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){}
public:
void Write(String^ message, FileStream^ stream){}
void Write(String^ message, FileStream^ stream, bool closeStream){}
이 지침에는 다음과 같은 두 가지 제약 조건이 있습니다.
오버로드에서 가변 인수 목록을 사용하는 경우 해당 목록은 최신 매개 변수여야 합니다.
오버로드에서 out 매개 변수를 사용하는 경우 규칙에 따라 마지막 매개 변수로 표시되어야 합니다.
확장성이 필요한 경우 가장 긴 오버로드만 virtual(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.
}
public:
void Write(String^ message, FileStream^ stream)
{
this->Write(message, stream, false);
}
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)
public:
void Write(String^ message, int count)
...
void Write(String^ message, 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);
}
}
public:
void CopyFile(FileInfo^ source, DirectoryInfo^ destination, String^ newName)
{
if (newName == nullptr)
{
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.
디자인 지침에 자세한 내용은 참조를 "Framework 디자인 지침: 규칙, 숙어, 및 재사용에 대 한 패턴입니다.NET 라이브러리"도 서 Krzysztof Cwalina와 Brad Abrams, 게시 Addison-wesley, 2005.