Condividi tramite


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

    - oppure -

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

Regole correlate

CA1059: I membri non devono esporre tipi concreti specifici