CA1011:建議將基底類型當做參數傳遞
型別名稱 |
ConsiderPassingBaseTypesAsParameters |
CheckId |
CA1011 |
分類 |
Microsoft.Design |
中斷變更 |
中斷 |
原因
方法宣告中包含屬於衍生型別 (Derived Type) 的型式參數,但該方法只會呼叫該參數的基底型別 (Base Type) 成員。
規則描述
當方法宣告將基底型別指定為參數,則從此基底型別衍生的任何型別都可以當做對應引數傳遞給方法。在方法主體內使用引數時,執行的特定方法需視引數型別而定。如果不需要以衍生型別提供額外的功能,則可以使用基底型別讓方法獲得更廣泛的使用。
如何修正違規
若要修正此規則的違規情形,請將參數型別變更為基底型別。
隱藏警告的時機
您可以放心地隱藏這項規則的警告。
如果方法需要衍生型別所提供的特定功能
-或-
強制只能將衍生型別或衍生程度更大的型別傳遞至方法。
在這些情況下,因為編譯器和執行階段提供了強式型別檢查,程式碼將會變得更強固。
範例
在下列範例中,程式碼會顯示方法 ManipulateFileStream,它僅可與違反此規則的 FileStream 物件一起使用。第二個方法 ManipulateAnyStream 會以 Stream 取代 FileStream 參數,以滿足此規則。
Imports System
Imports System.IO
Namespace DesignLibrary
Public Class StreamUser
Sub ManipulateFileStream(ByVal stream As IO.FileStream)
If stream Is Nothing Then Throw New ArgumentNullException("stream")
Dim anInteger As Integer = stream.ReadByte()
While (anInteger <> -1)
' Do something.
anInteger = stream.ReadByte()
End While
End Sub
Sub ManipulateAnyStream(ByVal anyStream As IO.Stream)
If anyStream Is Nothing Then Throw New ArgumentNullException("anyStream")
Dim anInteger As Integer = anyStream.ReadByte()
While (anInteger <> -1)
' Do something.
anInteger = anyStream.ReadByte()
End While
End Sub
End Class
Public Class TestStreams
Shared Sub Main()
Dim someStreamUser As New StreamUser()
Dim testFileStream As New FileStream( _
"test.dat", FileMode.OpenOrCreate)
Dim testMemoryStream As New MemoryStream(New Byte() {})
' Cannot be used with testMemoryStream.
someStreamUser.ManipulateFileStream(testFileStream)
someStreamUser.ManipulateAnyStream(testFileStream)
someStreamUser.ManipulateAnyStream(testMemoryStream)
testFileStream.Close()
End Sub
End Class
End Namespace
using System;
using System.IO;
namespace DesignLibrary
{
public class StreamUser
{
int anInteger;
public void ManipulateFileStream(FileStream stream)
{
while ((anInteger = stream.ReadByte()) != -1)
{
// Do something.
}
}
public void ManipulateAnyStream(Stream anyStream)
{
while ((anInteger = anyStream.ReadByte()) != -1)
{
// Do something.
}
}
}
class TestStreams
{
static void Main()
{
StreamUser someStreamUser = new StreamUser();
MemoryStream testMemoryStream = new MemoryStream(new byte[] { });
using (FileStream testFileStream =
new FileStream("test.dat", FileMode.OpenOrCreate))
{
// Cannot be used with testMemoryStream.
someStreamUser.ManipulateFileStream(testFileStream);
someStreamUser.ManipulateAnyStream(testFileStream);
someStreamUser.ManipulateAnyStream(testMemoryStream);
}
}
}
}
using namespace System;
using namespace System::IO;
namespace DesignLibrary
{
public ref class StreamUser
{
int anInteger;
public:
void ManipulateFileStream(FileStream^ stream)
{
while((anInteger = stream->ReadByte()) != -1)
{
// Do something.
}
}
void ManipulateAnyStream(Stream^ anyStream)
{
while((anInteger = anyStream->ReadByte()) != -1)
{
// Do something.
}
}
};
}
using namespace DesignLibrary;
static void main()
{
StreamUser^ someStreamUser = gcnew StreamUser();
FileStream^ testFileStream =
gcnew FileStream("test.dat", FileMode::OpenOrCreate);
MemoryStream^ testMemoryStream =
gcnew MemoryStream(gcnew array<Byte>{});
// Cannot be used with testMemoryStream.
someStreamUser->ManipulateFileStream(testFileStream);
someStreamUser->ManipulateAnyStream(testFileStream);
someStreamUser->ManipulateAnyStream(testMemoryStream);
testFileStream->Close();
}