[C#] Création de méthodes avec paramètres optionnels

Reuh,

N’ayant rien trouvé sur MSDN, est il possible d’implémenter une méthode ayant des paramètres optionnels sans pour autant faire des surcharges de méthode ? Et si oui, quel est la syntaxe ?

J’ai lu qq truc similaire avec les et les , mais ca ne correspond pas à ce que je veux. Vu qu’il faut tout de meme définir la variable optionnel à l’appel de méthode.

Ce que je veux si mon explication n’est pas claire c’est obtenir ce genre de truc :

[code]public my_function( param 1, param 2, <type_inconnu_optionnel> param 3)
{
// Instructions
}

public void Main()
{
string prefix;
string suffixe;
string middle;
my_function(prefix, suffix);
my_function(prefix, suffix, middle);
}[/code]

[quote=“MetalDestroyer, post:1, topic: 44771”]Reuh,

N’ayant rien trouvé sur MSDN, est il possible d’implémenter une méthode ayant des paramètres optionnels sans pour autant faire des surcharges de méthode ? Et si oui, quel est la syntaxe ?

J’ai lu qq truc similaire avec les et les , mais ca ne correspond pas à ce que je veux. Vu qu’il faut tout de meme définir la variable optionnel à l’appel de méthode.

Ce que je veux si mon explication n’est pas claire c’est obtenir ce genre de truc :

[code]public my_function( param 1, param 2, <type_inconnu_optionnel> param 3)
{
// Instructions
}

public void Main()
{
string prefix;
string suffixe;
string middle;
my_function(prefix, suffix);
my_function(prefix, suffix, middle);
}[/code][/quote]

Non. Ou alors j’avais vraiment mal cherché à l’époque. Au pire, ce que tu peux faire, c’est un truc genre

[code]public my_function( param 1, param 2, object param 3)
{ }

public void mon_autre_fonction()
{
my_function(p1, p2, null);
}[/code]

Eventuellement, tu peux aussi remplacer juste object par un array d’object. Et après, pour touver de quel type est le parametre, tu le teste avec un is, genre :

[code]if(param3 is string)
{

}
else if(param3 is MonTruc)
{

}[/code]

etc.

Donc, il n’y a vraiment pas d’autre choix que de mettre tous les paramètres dans la méthode. Celà dit, j’aimerais plus de feedback, ne sait on jamais ^^.

A titre perso, j’aime bien l’array d’object. Extensible à mort et si tous tes types sont différents, tu peux même te permettre de les mettre en désordre.

En attendant plus de feedback

C’est quelque chose qui existe en vb.net, qui est géré par l’IL (au travers du mot clé [opt]), mais qui n’a pas été implémenté en c# (by design, et je trouve leur choix relativement judicieux une fois que tu as vu comment l’IL l’utilisait).

C’est une horreur de faire ca je trouve perso B) Recette pour encourager les design boiteux, bien content que ca existe pas en C#. Voila c’est que mon opinion hein z’en faites ce que vous voulez…

J’ai été bien plus soft, mais +1 B)

Pour expliquer un peu, une fois qu’on a lu le second lien, çaa sent le truc présent pour faire plaisir aux dev vb B)

Vu qu’au final cette option ne fait que masquer un passage d’argument avec une valeur implicite par défaut, l’intérêt s’approche très fort du néant total.

hey les gars, avant de cracher dans la soupe, penser au printf,sprintf et compagnie…
y a pas de vararg en c# ?

Si si, mais c’est pas pareil que ce qui est demandé ici au depart (et en plus c’est que du sucre syntaxique au dessus d’un object[]).

Histoire de joindre l’utile à l’agréable, et mieux que des mots… démo (comme diraient les autres) :

Les arguments variables existent en c# avec le mot clé params :

public static void Main(params string[] args) { }

En vb, c’est ParamArray qui prend le relais :

Public Shared Sub Main(ByVal ParamArray args() as String) End Sub

Ouala

Comme le soulevais qqu’un dans un des commentaires d’un des liens de styx, object a juste un défaut, c’est qu’il ruine tous les avantages d’Intellisense et du compilateur, qui n’a aucune idée de ce qu’on lui fait dans le dos (bon ok, surtout intellisense en fait). Et en tant que gros glucidodépendant, il y a quelques cas ou j’aurais bien fait ma fainéasse avec des variables par défaut. Bon, ceci dit, c’est pas pour le temps que ca prend de s’en passer (genre 15s à tout casser, si tu tape pas vite).

C’est pas censé etre fait en partie pour ca la surcharge de methode ? et sinon params F1 oui, comme styx.

Donc si j’ai compris, le params est à éviter faute de pouvoir controller l’ordre et le type des données qu’on veut traiter et le fait de casser l’intellisense. Il faut donc forcément passer par la méthode que bishop m’a fournit en tout début du topic ?

Glop -> bah, je pensais que le comportement d’une telle implémentation était trivial et n’apportait aucune contrainte. Là quand je lis ce que je vois, c’est clair j’ai vite envie de pas l’utiliser. C’est dommage >_<

Si c’est pour faire un MaFonction(params object args), oui, c’est à éviter. Vu que dans ton cas à priori les paramètres sont de type différents, vu qu’ensuite tu serais obligé de faire du cast et cie pour contrôler tes types.

Bref, fais plusieurs méthodes avec des paramètres en moins, et qui appellent la plus complète qui contient l’implémentation réelle, c’est ce que l’on (que je) fais en général

[code]void MyFunction(string message)
{
MyFunction(message, -1, false);
}

void MyFunction(string message, bool critical)
{
MyFunction(message, -1, critical);
}

void MyFunction(string message, int category)
{
MyFunction(message, category, false);
}

void MyFunction(string message, int category, bool critical)
{
// Ton vrai code ici
}[/code]

ça sert juste à coder des fonctions comme printf le Object[] non ?

Ca sert surtout à simplifier les appels de méthodes ou l’on doit passer un tableau de valeurs.
Par exemple, si tu prends System.String.Format, sa définition ressemble plus ou moins à ça (manque les paramètres de formatage, la gestion des exceptions etc…) :

[codebox]public class String
{

public static string Format(string formatString, params object[] parameters)
{
// version simplifiée du code :
StringBuilder sb = new StringBuilder(formatString);
for(int i = 0; i<parameters.Length; i++)
{
sb.Replace("{"+i.ToString()+"}", parameters[i].ToString());
}
return sb.ToString();
}

}
[/codebox]

A l’appel tu vas faire : string.Format("{0} : {1}", DateTime.Now, currentException.Message); par exemple.
Le params est simplement là pour simplifier l’appel, et transformer une liste de paramètres en tableau.
Au passage, dans cet exemple, on a un tableau d’object, mais on peut avoir des params typés :

[codebox]public class ArrayTool
{
public static T[] MakeArrayFromList(params T[] list)
{
return list;
}
}
[/codebox]
Voilà voilà!