Méthodes avec retour de plusieurs valeurs
"Pourquoi se contenter d’une seule réponse quand on peut en avoir plusieurs ?" ✨
Qu’est-ce qu’une méthode avec retour multiple ?
Depuis C# 7, une méthode peut retourner plusieurs valeurs sans utiliser out ou des classes/structures.
➡️ Cela est rendu possible grâce aux tuples ((type1, type2, …)).
💡 Les tuples permettent de regrouper plusieurs valeurs dans un seul objet facile à manipuler.
Structure générale
static (<Type1>, <Type2>, ...) NomMethode(<paramètres>)
{
// traitement
return (valeur1, valeur2, ...);
}
Exemple simple
static (int somme, int produit) Calculer(int a, int b)
{
int s = a + b;
int p = a * b;
return (s, p);
}
Utilisation :
var resultats = Calculer(3, 5);
Console.WriteLine($"Somme : {resultats.somme}, Produit : {resultats.produit}");
// Somme : 8, Produit : 15
🧠 Explication
Le type de retour ici est un tuple (int, int), c’est-à-dire une valeur composée de deux éléments.
➡️ Cela permet de regrouper plusieurs résultats dans une seule structure, sans créer de classe ni utiliser out.
🔍 Détail du fonctionnement
static (int somme, int produit) Calculer(int a, int b)
{
int s = a + b;
int p = a * b;
return (s, p);
}
(int somme, int produit)→ indique que la méthode renvoie deux entiersreturn (s, p);→ crée un tuple contenant deux valeurs- Les noms
sommeetproduitpermettent de donner un sens à chaque élément
Quand tu appelles la méthode :
var resultats = Calculer(3, 5);
Console.WriteLine(resultats.somme); // 8
Console.WriteLine(resultats.produit); // 15
⚠️ Important : Item1 / Item2 et tuples nommés
Il existe deux familles de tuples en .NET :
- Tuple<...> (classe, .NET 4.x) — accès via Item1, Item2, …
- ValueTuple<...> (type valeur, C# 7+) — accès via noms (ex. somme, produit) et via Item1, Item2, …
Avec les tuples nommés en C# 7+, les deux accès fonctionnent :
var r = Calculer(3, 5);
Console.WriteLine(r.somme); // ✅ 8
Console.WriteLine(r.produit);// ✅ 15
Console.WriteLine(r.Item1); // ✅ 8 (nom par défaut toujours disponible)
Console.WriteLine(r.Item2); // ✅ 15
✅ Les noms par défaut
Item1,Item2, etc. restent utilisables même si vous avez donné des noms explicites aux éléments.
💡 Cependant, certains IDE peuvent privilégier l’auto-complétion sur les noms explicites pour la lisibilité.
Si tu n’attribues pas de noms :
static (int, int) Calculer(int a, int b) => (a + b, a * b);
var r = Calculer(3, 5);
Console.WriteLine(r.Item1); // ✅ 8
Console.WriteLine(r.Item2); // ✅ 15
| Déclaration | Accès possible | Recommandé |
|---|---|---|
(int somme, int produit) |
r.somme, r.produit, r.Item1, r.Item2 |
✅ Utiliser les noms pour la clarté |
(int, int) |
r.Item1, r.Item2 |
⚠️ OK mais moins expressif |
Tuple<int,int> |
Item1, Item2 (classe, plus lourde) |
🚫 À éviter pour du code moderne |
✨ Autre exemple : une méthode qui retourne des statistiques
Voici un exemple plus concret : une méthode qui retourne la moyenne et la note la plus haute d’un tableau d’étudiants 🎓
static (double moyenne, int max) AnalyserNotes(int[] notes)
{
double moyenne = notes.Average();
int max = notes.Max();
return (moyenne, max);
}
Utilisation :
var resultats = AnalyserNotes(new int[] { 10, 14, 18, 7, 12 });
Console.WriteLine($"Moyenne : {resultats.moyenne}, Meilleure note : {resultats.max}");
📤 Résultat :
Moyenne : 12.2, Meilleure note : 18
🧩 À retenir
| Accès | Exemple | Résultat |
|---|---|---|
| Par nom | resultats.moyenne |
12.2 |
| Par position (si noms absents) | resultats.Item1 |
12.2 |
| Tuple complet | (12.2, 18) |
Affiche les deux valeurs ensemble |
💬 Les tuples rendent ton code plus clair quand une méthode doit renvoyer plusieurs informations liées.
Déstructuration d’un tuple
Tu peux décomposer le tuple directement à la réception :
(int somme, int produit) = Calculer(4, 6);
Console.WriteLine($"Somme : {somme}, Produit : {produit}");
💡 Très pratique pour éviter d’avoir à manipuler un objet intermédiaire.
Exemple complet
static (int min, int max) TrouverBornes(int[] tableau)
{
int min = tableau.Min();
int max = tableau.Max();
return (min, max);
}
static void Main()
{
int[] nombres = { 5, 2, 9, 1, 7 };
var (min, max) = TrouverBornes(nombres);
Console.WriteLine($"Minimum : {min}, Maximum : {max}");
}
📤 Résultat :
Minimum : 1, Maximum : 9
💡 Bonnes pratiques : var vs type explicite
"Entre simplicité et clarté, le bon code choisit… les deux." ✨
var : pratique et moderne
var permet de laisser le compilateur déduire automatiquement le type d’une variable à partir de la valeur qui lui est assignée.
var resultat = Calculer(3, 5);
Console.WriteLine(resultat.somme);
✅ Avantages :
- Code plus court et lisible
- Moins de répétition de types
- Idéal quand le type est évident dans le contexte
⚠️ Attention :
- Le type est quand même déterminé à la compilation →
varn’est pas dynamique - Si le type n’est pas clair au premier regard, le code devient moins lisible
On peut aussi afficher le type complet pour plus de compréhension :
(int somme, int produit) resultat = Calculer(3, 5);
Console.WriteLine(resultat.produit);
✅ Avantages :
- Code plus explicite (on sait exactement ce que la méthode retourne)
- Plus facile pour les débutants
- Recommandé dans le cadre d’un cours ou d’une relecture de code
Recommandation pédagogique
- Commencer avec le type explicite → comprendre ce que la méthode retourne.
- Introduire ensuite
var→ montrer qu’il simplifie le code sans changer le comportement.
💬 "Le bon code est celui qu’on comprend, même sans le compilateur."
🧩 Quiz – var ou pas var ?
Testez vos connaissances ! 📝 Clique pour découvrir la réponse.
1️⃣ Que fait vraiment le mot-clé
var ?
B. Laisse le compilateur deviner le type
C. Rend la variable globale
D. Supprime le typage
E. Change le type à l’exécution
✅ Afficher la réponse
var laisse le compilateur inférer le type à la compilation.
2️⃣ Dans quel cas éviter
var ?
B. Quand le type est complexe ou peu clair
C. Toujours
D. Jamais
E. Quand on utilise un tuple
✅ Afficher la réponse
var quand le type n’est pas évident, pour garder un code clair.
3️⃣ Quelle est la différence entre
var resultat = Calculer(3, 5); et (int somme, int produit) resultat = Calculer(3, 5); ?var crée un type différent
B. var est plus lent
C. Aucune : le type est le même
D. La deuxième ligne crée une liste
E. var utilise le mot-clé dynamic
✅ Afficher la réponse
(int, int).
⚠️ Attention
- Les tuples ne remplacent pas les classes : ils sont utiles pour des retours temporaires
- Les noms des champs dans un tuple sont optionnels mais fortement recommandés
- Les tuples peuvent être imbriqués (
(int, (string, bool))) mais deviennent vite illisibles - Avant C# 7, il fallait utiliser
outou créer une classe/structure pour renvoyer plusieurs valeurs
Comparaison rapide
| Approche | Avantages | Inconvénients |
|---|---|---|
out |
Compatible avec toutes les versions de C# | Syntaxe plus lourde, nécessite déclaration préalable |
| Classe / struct | Lisible, extensible | Nécessite une définition externe |
| Tuple (C# 7+) | Rapide, simple, lisible | Moins adapté si le résultat doit être conservé longtemps |
Quiz
Testez vos connaissances ! 📝 Clique sur chaque question pour découvrir la réponse.
1️⃣ Que permet le tuple dans une méthode ?
B. De retourner plusieurs valeurs
C. D’exécuter plusieurs méthodes
D. De fusionner des boucles
E. D’éviter le mot-clé return
✅ Afficher la réponse
2️⃣ Quelle est la bonne déclaration ?
static tuple(int, int) Methode()
B. static (int, int) Methode()
C. static Tuple Methode()
D. static tuple<int, int> Methode()
E. static void Methode(int, int)
✅ Afficher la réponse
(int, int) sans mot-clé tuple.
3️⃣ Comment accéder à la deuxième valeur d’un tuple nommé ?
resultat.2
B. resultat.Item2
C. resultat[1]
D. resultat.produit
E. resultat.valeur2
✅ Afficher la réponse
resultat.produit).
4️⃣ Quelle est la différence entre
Tuple<int, int> et (int, int) ?
B. Le premier est une classe, le second est une nouvelle syntaxe simplifiée (C# 7+)
C. Le premier est plus rapide
D. Le second ne fonctionne qu’avec ref
E. Le premier est réservé à LINQ
✅ Afficher la réponse
Tuple<int, int> crée un objet de classe, alors que (int, int) est un type valeur plus léger et moderne.
5️⃣ Quelle syntaxe déstructure le tuple ?
(a, b) = Methode();
B. tuple = Methode(a, b);
C. int a = tuple(0);
D. return (a, b);
E. tuple[a, b] = Methode();
✅ Afficher la réponse
(a, b) = Methode();.
Navigation
Introduction Sans paramètre Avec paramètre Avec retour Par référence / Out Retour multiple (out) Retour multiple (tuples) Travail pratique
Pour aller plus loin
-
Types Tuple (référence C#) Référence officielle sur les
ValueTuple(accès par noms etItem1/Item2, déconstruction, etc.). -
Tutoriel interactif – Tuples et types Pas-à-pas interactif pour manipuler des tuples et comparer avec
record,structetclass.
-
TutorialsTeacher – C# Tuple Présentation claire des tuples (classe
Tuple<T>etValueTuple). -
Programiz – C# Tuples (With Examples) Exemples simples (création, accès, déstructuration).