Partager via


Méthodes (Guide de programmation C#)

Une méthode est un bloc de code qui contient une série d'instructions. Un programme provoque l'exécution des instructions en appelant la méthode et en spécifiant les éventuels arguments de méthode requis. En C#, chaque instruction exécutée est effectuée dans le contexte d'une méthode.

La Main méthode est le point d’entrée de chaque application C# et elle est appelée par le Common Language Runtime (CLR) au démarrage du programme. Dans une application qui utilise des instructions de niveau supérieur, la Main méthode est générée par le compilateur et contient toutes les instructions de niveau supérieur.

Remarque

Cet article traite des méthodes nommées. Pour plus d’informations sur les fonctions anonymes, consultez Expressions lambda.

Signatures de méthode

Les méthodes sont déclarées dans une classe, un struct ou une interface en spécifiant le niveau d’accès tel que public ou privateles modificateurs facultatifs tels que abstract ou sealed, la valeur de retour, le nom de la méthode et tous les paramètres de méthode. Ces parties sont ensemble la signature de la méthode.

Importante

Un type de retour d'une méthode ne fait pas partie de la signature de la méthode à des fins de surcharge de méthode. Toutefois, il fait partie de la signature de la méthode lors de la détermination de la compatibilité entre un délégué et la méthode vers laquelle il pointe.

Les paramètres de méthode sont placés entre parenthèses et séparés par des virgules. Des parenthèses vides indiquent que la méthode ne requiert aucun paramètre. Cette classe contient quatre méthodes :

abstract class Motorcycle
{
    // Anyone can call this.
    public void StartEngine() {/* Method statements here */ }

    // Only derived classes can call this.
    protected void AddGas(int gallons) { /* Method statements here */ }

    // Derived classes can override the base class implementation.
    public virtual int Drive(int miles, int speed) { /* Method statements here */ return 1; }

    // Derived classes must implement this.
    public abstract double GetTopSpeed();
}

Accès aux méthodes

L’appel d’une méthode sur un objet ressemble à l’accès à un champ. Après le nom de l’objet, ajoutez un point, le nom de la méthode et des parenthèses. Les arguments sont répertoriés entre parenthèses et sont séparés par des virgules. Les méthodes de la Motorcycle classe peuvent donc être appelées comme dans l’exemple suivant :

class TestMotorcycle : Motorcycle
{
    public override double GetTopSpeed()
    {
        return 108.4;
    }

    static void Main()
    {
        TestMotorcycle moto = new TestMotorcycle();

        moto.StartEngine();
        moto.AddGas(15);
        moto.Drive(5, 20);
        double speed = moto.GetTopSpeed();
        Console.WriteLine($"My top speed is {speed}");
    }
}

Paramètres de méthode et arguments

La définition de la méthode spécifie les noms et types des paramètres requis. Lorsqu’un code d’appel invoque la méthode, il fournit des valeurs concrètes appelées arguments pour chaque paramètre. Les arguments doivent être compatibles avec le type de paramètre, mais le nom de l’argument (le cas échéant) utilisé dans le code appelant n’a pas besoin d’être identique au paramètre nommé défini dans la méthode. Par exemple:

public void Caller()
{
    int numA = 4;
    // Call with an int variable.
    int productA = Square(numA);

    int numB = 32;
    // Call with another int variable.
    int productB = Square(numB);

    // Call with an integer literal.
    int productC = Square(12);

    // Call with an expression that evaluates to int.
    productC = Square(productA * 3);
}

int Square(int i)
{
    // Store input argument in a local variable.
    int input = i;
    return input * input;
}

Passer par référence et passer par valeur

Par défaut, lorsqu’une instance d’un type valeur est passée à une méthode, sa copie est passée au lieu de l’instance elle-même. Par conséquent, les modifications apportées à l’argument n’ont aucun effet sur l’instance d’origine dans la méthode appelante. Pour passer une instance de type valeur par référence, utilisez le ref mot clé. Pour plus d’informations, consultez Passage de paramètres Value-Type.

Lorsqu’un objet d’un type référence est passé à une méthode, une référence à l’objet est passée. Autrement dit, la méthode ne reçoit pas l’objet lui-même, mais un argument qui indique l’emplacement de l’objet. Si vous modifiez un membre de l’objet à l’aide de cette référence, la modification est reflétée dans l’argument de la méthode appelante, même si vous passez l’objet par valeur.

Vous créez un type de référence à l’aide du class mot clé, comme l’illustre l’exemple suivant :

public class SampleRefType
{
    public int value;
}

Maintenant, si vous passez un objet basé sur ce type à une méthode, une référence à l’objet est passée. L’exemple suivant transmet un objet de type SampleRefType à la méthode ModifyObject:

public static void TestRefType()
{
    SampleRefType rt = new SampleRefType();
    rt.value = 44;
    ModifyObject(rt);
    Console.WriteLine(rt.value);
}

static void ModifyObject(SampleRefType obj)
{
    obj.value = 33;
}

L’exemple fait essentiellement la même chose que l’exemple précédent dans lequel il transmet un argument par valeur à une méthode. Toutefois, étant donné qu’un type référence est utilisé, le résultat est différent. La modification apportée au ModifyObjectvalue champ du paramètre, objmodifie également le value champ de l’argument, rtdans la TestRefType méthode. La TestRefType méthode affiche 33 comme sortie.

Pour plus d'informations sur la façon de passer des types de référence par référence et par valeur, consultez Passage de Reference-Type Paramètres et Types de Référence.

Valeurs de retour

Les méthodes peuvent retourner une valeur à l'appelant. Si le type de retour (le type répertorié avant le nom de la méthode) n’est pas void, la méthode peut renvoyer la valeur à l’aide de l’instructionreturn. Une instruction avec le return mot clé suivi d’une valeur qui correspond au type de retour retourne cette valeur à l’appelant de méthode.

La valeur peut être retournée à l’appelant par valeur ou par référence. Les valeurs sont retournées à l’appelant par référence si le ref mot clé est utilisé dans la signature de méthode et qu’il suit chaque return mot clé. Par exemple, la signature de méthode et l’instruction return suivantes indiquent que la méthode retourne une variable nommée estDistance par référence à l’appelant.

public ref double GetEstimatedDistance()
{
    return ref estDistance;
}

Le mot clé return arrête également l'exécution de la méthode. Si le type de retour est void, une instruction return sans valeur est quand même utile pour arrêter l'exécution de la méthode. Sans le return mot clé, la méthode cesse de s’exécuter lorsqu’elle atteint la fin du bloc de code. Les méthodes avec un type de retour non vide doivent utiliser le mot clé return pour renvoyer une valeur. Par exemple, ces deux méthodes utilisent le mot clé return pour retourner des entiers :

class SimpleMath
{
    public int AddTwoNumbers(int number1, int number2)
    {
        return number1 + number2;
    }

    public int SquareANumber(int number)
    {
        return number * number;
    }
}

Pour utiliser une valeur retournée à partir d’une méthode, la méthode appelante peut utiliser l’appel de méthode lui-même n’importe où une valeur du même type serait suffisante. Vous pouvez également affecter la valeur de retour à une variable. Par exemple, les deux exemples de code suivants réalisent le même objectif :

int result = obj.AddTwoNumbers(1, 2);
result = obj.SquareANumber(result);
// The result is 9.
Console.WriteLine(result);
result = obj.SquareANumber(obj.AddTwoNumbers(1, 2));
// The result is 9.
Console.WriteLine(result);

L’utilisation d’une variable locale, dans ce cas, resultpour stocker une valeur est facultative. Il peut aider à la lisibilité du code, ou il peut être nécessaire si vous devez stocker la valeur d’origine de l’argument pour l’ensemble de la portée de la méthode.

Pour utiliser une valeur retournée par référence à partir d’une méthode, vous devez déclarer une variable locale ref si vous envisagez de modifier sa valeur. Par exemple, si la Planet.GetEstimatedDistance méthode retourne une Double valeur par référence, vous pouvez la définir comme variable locale ref avec du code comme suit :

ref double distance = ref Planet.GetEstimatedDistance();

Retourner un tableau multidimensionnel à partir d’une méthode, Mqui modifie le contenu du tableau n’est pas nécessaire si la fonction appelante a passé le tableau en M. Vous pouvez retourner le tableau obtenu à partir de M pour des raisons de style ou une gestion fonctionnelle des valeurs, cependant, ce n'est pas nécessaire, car C# transmet tous les types de référence par valeur, et qu'une référence de tableau est le pointeur vers le tableau. Dans la méthode M, toutes les modifications apportées au contenu du tableau sont observables par n’importe quel code qui a une référence au tableau, comme illustré dans l’exemple suivant :

static void Main(string[] args)
{
    int[,] matrix = new int[2, 2];
    FillMatrix(matrix);
    // matrix is now full of -1
}

public static void FillMatrix(int[,] matrix)
{
    for (int i = 0; i < matrix.GetLength(0); i++)
    {
        for (int j = 0; j < matrix.GetLength(1); j++)
        {
            matrix[i, j] = -1;
        }
    }
}

Méthodes asynchrones

La fonctionnalité async vous permet d'appeler des méthodes asynchrones sans utiliser de rappels explicites ni fractionner manuellement votre code entre plusieurs méthodes ou expressions lambda.

Si vous marquez une méthode avec le modificateur async, vous pouvez utiliser l’opérateur await dans la méthode. Lorsque le contrôle atteint une expression await dans la méthode asynchrone, le contrôle retourne à l’appelant et la progression de la méthode est suspendue jusqu’à ce que la tâche attendue se termine. Quand la tâche est terminée, l'exécution peut reprendre dans la méthode.

Remarque

Une méthode asynchrone retourne à l'appelant quand elle rencontre le premier objet attendu qui n'est pas encore terminé ou quand elle atteint la fin de la méthode asynchrone, selon la première éventualité.

Une méthode asynchrone a généralement un type de retour de Task<TResult>, TaskIAsyncEnumerable<T>ou void. Le type de retour void est essentiellement utilisé pour définir les gestionnaires d’événements, où un type de retour void est obligatoire. Une méthode async qui retourne void ne peut pas être attendue, et l’appelant d’une méthode retournant void ne peut intercepter aucune exception levée par la méthode. Une méthode asynchrone peut avoir n’importe quel type de retour de type tâche.

Dans l’exemple suivant, DelayAsync est une méthode asynchrone qui a un type de retour .Task<TResult> DelayAsync a une instruction qui retourne un return entier. Par conséquent, la déclaration de méthode de DelayAsync doit avoir un type de retour Task<int>. Étant donné que le type de retour est Task<int>, l’évaluation de l’expression await dans DoSomethingAsync produit un entier comme l’instruction suivante illustre : int result = await delayTask.

La méthode Main est un exemple de méthode asynchrone qui a un type de retour de Task. Il va à la méthode DoSomethingAsync, et parce qu'il est exprimé avec une seule ligne, il peut omettre les mots clés async et await. Étant donné que DoSomethingAsync est une méthode asynchrone, il faut attendre la tâche de l'appel à DoSomethingAsync, comme l'indique l'instruction suivante : await DoSomethingAsync();.

class Program
{
    static Task Main() => DoSomethingAsync();

    static async Task DoSomethingAsync()
    {
        Task<int> delayTask = DelayAsync();
        int result = await delayTask;

        // The previous two statements may be combined into
        // the following statement.
        //int result = await DelayAsync();

        Console.WriteLine($"Result: {result}");
    }

    static async Task<int> DelayAsync()
    {
        await Task.Delay(100);
        return 5;
    }
}
// Example output:
//   Result: 5

Une méthode asynchrone ne peut déclarer aucun paramètre ref ou out , mais elle peut appeler des méthodes qui ont de tels paramètres.

Pour plus d’informations sur les méthodes asynchrones, consultez Programmation asynchrone avec asynchrone et await et Types de retour asynchrones.

Définitions de corps d’expression

Il est courant d’avoir des définitions de méthode qui retournent simplement immédiatement avec le résultat d’une expression, ou qui ont une instruction unique comme corps de la méthode. Il existe un raccourci de syntaxe pour définir ces méthodes à l’aide =>de :

public Point Move(int dx, int dy) => new Point(x + dx, y + dy);
public void Print() => Console.WriteLine(First + " " + Last);
// Works with operators, properties, and indexers too.
public static Complex operator +(Complex a, Complex b) => a.Add(b);
public string Name => First + " " + Last;
public Customer this[long id] => store.LookupCustomer(id);

Si la méthode retourne void ou est une méthode asynchrone, le corps de la méthode doit être une expression d’instruction (identique à celle des lambdas). En ce qui concerne les propriétés et indexeurs, ils doivent être en lecture seule et vous n'utilisez pas le mot clé d'accesseur get.

Itérateurs

Un itérateur exécute une itération personnalisée sur une collection, comme une liste ou un tableau. Un itérateur utilise l'instruction yield return pour retourner chaque élément un par un. Lorsqu’une yield return instruction est atteinte, l’emplacement actuel dans le code est mémorisé. L’exécution est redémarrée à partir de cet emplacement lorsque l’itérateur est appelé la prochaine fois.

Vous appelez un itérateur à partir du code client à l’aide d’une instruction foreach .

Le type de retour d'un itérateur peut être IEnumerable, IEnumerable<T>, IAsyncEnumerable<T>, IEnumerator ou IEnumerator<T>.

Pour plus d'informations, consultez Itérateurs.

Spécification du langage C#

Pour plus d'informations, voir la spécification du langage C#. La spécification du langage est la source de référence pour la syntaxe C# et son utilisation.

Voir aussi