Поделиться через


CA1011: попробуйте передать базовые типы в качестве параметров

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();
}

Связанные правила

CA1059: члены не должны предоставлять определенные устойчивые типы