Попробуйте передать базовые типы в качестве параметров
Обновлен: Ноябрь 2007
TypeName |
ConsiderPassingBaseTypesAsParameters |
CheckId |
CA1011 |
Категория |
Microsoft.Design |
Критическое изменение |
Критическое |
Причина
В объявлении метода содержится формальный параметр, принадлежащий производному типу, тогда как метод вызывает только члены базового типа параметра.
Описание правила
Если в объявлении метода в качестве параметра указан базовый тип, любой тип, производный от базового, можно передать методу в качестве соответствующего аргумента. Если аргумент используется в основной части метода, конкретное выполнение метода зависит от типа аргумента. Если дополнительные функции, предоставляемые производным типом, не требуются, то использование базового типа позволит более широко применять данный метод.
Предотвращение нарушений
Чтобы устранить нарушение данного правила, замените тип параметра на базовый тип.
Отключение предупреждений
Если в методе требуется реализовать особые функциональные возможности, предоставляемые производным типом, или необходимо обеспечить передачу в метод только производных типов первого или одного из следующих уровней в цепочке наследования, то отключение предупреждений о нарушении данного правила будет безопасным. В таком случае код будет более устойчивым благодаря строгой проверке типов, обеспечиваемой компилятором и средой выполнения.
Пример
В следующем примере показан метод ManipulateFileStream, который может использоваться только с объектом FileStream, что нарушает данное правило. Второй метод — ManipulateAnyStream — удовлетворяет правилу благодаря замене параметра FileStream на параметр 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();
}