CA1011 : Si possible, transmettez les types de base en tant que paramètres

TypeName

ConsiderPassingBaseTypesAsParameters

CheckId

CA1011

Catégorie

Microsoft.CSharp

Modification avec rupture

Oui

Cause

Une déclaration de méthode comprend un paramètre formel qui constitue un type dérivé, et la méthode appelle seulement des membres du type de base du paramètre.

Description de la règle

Lorsqu'un type de base est spécifié en tant que paramètre dans une déclaration de méthode, tout type dérivé du type de base peut être passé en tant qu'argument correspondant à la méthode. Lorsque l'argument est utilisé à l'intérieur du corps de méthode, la méthode spécifique exécutée dépend du type de l'argument. Si les fonctionnalités supplémentaires fournies par le type dérivé ne sont pas requises, l'utilisation du type de base autorise une exploitation plus large de la méthode.

Comment corriger les violations

Pour corriger une violation de cette règle, changez le type du paramètre en son type de base.

Quand supprimer les avertissements

Il est possible de supprimer sans risque un avertissement de cette règle

  • si la méthode requiert la fonctionnalité spécifique qui est fournie par le type dérivé

    - ou -

  • pour s'assurer que seul le type dérivé, ou un type plus dérivé, est passé à la méthode.

Dans ces cas, le code est plus fiable en raison de la vérification des types forts fournie par le compilateur et le moteur d'exécution.

Exemple

L'exemple suivant présente une méthode, ManipulateFileStream, qui ne peut être utilisée qu'avec un objet FileStream qui viole cette règle. Une seconde méthode, ManipulateAnyStream, satisfait la règle en remplaçant le paramètre FileStream à l'aide d'un 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();
}

Règles connexes

CA1059 : Les membres ne doivent pas exposer certains types concrets