Udostępnij za pośrednictwem


CA1011: Należy rozważyć przekazywanie typów bazowych jako parametrów

TypeName

ConsiderPassingBaseTypesAsParameters

CheckId

CA1011

Kategoria

Microsoft.Design

Zmiana kluczowa

Kluczowa

Przyczyna

Deklaracja metody zawiera formalny parametr, który jest typem pochodnym i metoda wywołuje tylko elementy członkowskie podstawowego typu parametru.

Opis reguły

Po określeniu typu podstawowego jako parametru w deklaracji metody, dowolny typ, który pochodzi od typu podstawowego może być przekazany jako odpowiadający argument metody.Gdy argument jest używany wewnątrz treści metody, określona metoda, która jest wykonywana, zależy od typu argumentu.Jeśli dodatkowa funkcjonalność, która jest dostarczana przez typ pochodny nie jest wymagana, użycie typu podstawowego umożliwia szersze wykorzystanie metody.

Jak naprawić naruszenia

Aby naprawić naruszenie tej zasady, należy zmienić typ parametru na jego typ podstawowy.

Kiedy pominąć ostrzeżenia

Bezpiecznie jest wyłączyć ostrzeżenia dotyczące tej zasady

  • jeżeli metoda wymaga określonych funkcji, dostarczanych przez typ pochodny

    - lub -

  • aby wymusić tylko typ pochodny, lub bardziej pochodny typ jest przekazywany do metody.

W tych przypadkach kod będzie bardziej niezawodny ze względu na sprawdzanie silnego typowania, które jest dostarczane przez kompilator i środowisko uruchomieniowe.

Przykład

Poniższy przykład ilustruje metodę ManipulateFileStream, która może zostać użyta tylko z obiektem FileStream, naruszając regułę.Druga metoda ManipulateAnyStream, spełnia regułę, zastępując parametr FileStream za pomocą 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();
}

Powiązane reguły

CA1059: Elementy członkowskie nie powinny uwidaczniać pewnych typów konkretnych