CA1011: Considerare il passaggio di tipi di base come parametri
TypeName |
ConsiderPassingBaseTypesAsParameters |
CheckId |
CA1011 |
Category |
Microsoft.Design |
Breaking Change |
Breaking |
Causa
Una dichiarazione di metodo include un parametro formale costituito da un tipo derivato e il metodo chiama solo membri del tipo di base del parametro.
Descrizione della regola
Quando un tipo di base viene specificato come parametro in una dichiarazione di metodo, qualsiasi tipo derivato dal tipo di base può essere passato al metodo come argomento corrispondente. Quando l'argomento viene utilizzato all'interno del corpo del metodo, il metodo specifico che viene eseguito dipende dal tipo dell'argomento. Se la funzionalità aggiuntiva fornita dal tipo derivato non è richiesta, l'utilizzo del tipo di base consente un utilizzo più esteso del metodo.
Come correggere le violazioni
Per correggere una violazione di questa regola, modificare il tipo del parametro nel relativo tipo di base.
Esclusione di avvisi
L'esclusione di un avviso da questa regola è sicura
se il metodo richiede la funzionalità specifica fornita dal tipo derivato
In alternativa
per imporre di passare al metodo solo il tipo derivato o un tipo più derivato.
In questi casi, il codice sarà più sicuro grazie al rigido controllo dei tipi fornito dal compilatore e dal runtime.
Esempio
Nell'esempio riportato di seguito viene illustrato il metodo ManipulateFileStream, che può essere utilizzato solo con un oggetto FileStream, il quale viola la regola. Un secondo metodo, ManipulateAnyStream, soddisfa la regola sostituendo il parametro FileStream mediante un oggetto Stream.
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();
}