Constructeur "intelligent" [Résolu]

Signaler
Messages postés
41
Date d'inscription
mardi 15 juillet 2003
Statut
Membre
Dernière intervention
7 décembre 2004
-
Messages postés
2368
Date d'inscription
mardi 17 avril 2001
Statut
Modérateur
Dernière intervention
26 décembre 2007
-
Bonjour

J'ai des class hérité de userControl et je voudrait passer les composant a une class qui les initilise et construit si besoin
pour cela j'ai fait :

public class toto:System.Window.Form.UserControl
{
....
}
public class titi:System.Window.Form.UserControl
{
...
}

public class ma_class
{
private titi val_titi;
private toto val_toto;

private ??? iniComosant(System.Window.Form.UserControl val)
{
if(val == null)
val = new ??????;
return val;
}
}

en gros, je voudrait que la fonction iniComposant reconnaisse le type de "val" et le construise avec son type d'origine...

je sais pas si je suis très clair...

21 réponses

Messages postés
2368
Date d'inscription
mardi 17 avril 2001
Statut
Modérateur
Dernière intervention
26 décembre 2007
20
Vous vous prenez trop la tête , ca devrait marché:

Type montype = typeof(arg);
Type[] types = new Type[1];
types[0] = typeokf(int) //arg 1
types[1] = typeof (string) //arg2
object[] param = new object[];

ConstructotInfo csinfo = monType.GetConstructor(BindingsFlags.Instance | BindingFlags.Public, null, CallingConvention.HasThis, types, null);

csinfo.Invoke(param);

::|The S@ib|::
MVP C#.NET
Messages postés
6351
Date d'inscription
samedi 1 juin 2002
Statut
Modérateur
Dernière intervention
2 août 2014
92
private void iniComosant(System.Window.Form.UserControl val)
{
if(val == null)
{
if ( val.GetType() == typeof(titi)
val = new titi(...);
if ( val.GetType() == typeof(toto)
val = new toto(...);
}
}


syntaxe exacte non garantie : je n'ai pas d'ide sous la main lol

Cocoricoooooooo !!!!
Messages postés
41
Date d'inscription
mardi 15 juillet 2003
Statut
Membre
Dernière intervention
7 décembre 2004

arfff vi... mais dans mon cas, toto et titi son entouré d'une bonne vingtaine de copains.. :(...
Messages postés
6351
Date d'inscription
samedi 1 juin 2002
Statut
Modérateur
Dernière intervention
2 août 2014
92
avec les parantheses ça ira deja mieux :
private void iniComosant(System.Window.Form.UserControl val)
{
if(val == null)
{
if ( val.GetType() == typeof(titi) )
val = new titi(...);
if ( val.GetType() == typeof(toto) )
val = new toto(...);
}
}


Cocoricoooooooo !!!!
Messages postés
6351
Date d'inscription
samedi 1 juin 2002
Statut
Modérateur
Dernière intervention
2 août 2014
92
ba dsl je ne vois pas d'autre solution dans l'immédiat

Cocoricoooooooo !!!!
Messages postés
41
Date d'inscription
mardi 15 juillet 2003
Statut
Membre
Dernière intervention
7 décembre 2004

merci quand meme bonne soirée
Messages postés
6814
Date d'inscription
dimanche 15 décembre 2002
Statut
Modérateur
Dernière intervention
13 octobre 2010
28
qd je vois ton problème je pense à une interface ...

j'ai pas le temps tout de suite, mais ca peut, peut etre vous donné une idée, si tu vois pas ce a quoi je pense, je vais m'expliquer un peu plus ;)

@+

Cyril
Messages postés
6351
Date d'inscription
samedi 1 juin 2002
Statut
Modérateur
Dernière intervention
2 août 2014
92
oui de toute façon il faudras certainement une interface, mon exemple au dessus ne tiens pas du tout la route

Cocoricoooooooo !!!!
Messages postés
6814
Date d'inscription
dimanche 15 décembre 2002
Statut
Modérateur
Dernière intervention
13 octobre 2010
28
ca fait une demi heure que j'y tourne autour je vois rien qui se dessine ....

J'ai essayé avec une interface, j'arrive à rien, je crois qu'il va falloir faire un peu de reflexion, mais je connais pas du tout ca.

mon idée en gros

Titi, Toto et ses amis héritent de MyUserControl qui lui meme hérite de UserControl

(je viens de me rendre compte que ce que je pensais n'est encore pas bon, mais je continue qd meme)

apres avec la reflexion, on fait un tableau de tout les types qui héritent de MyUserControl (Càd Titi, Toto et ses amis)
apres on bouclait sur le tableau de Type, on compare le type de val et du type de la boucle en cours

Le problème etait pour retourner le paramètre, mais en ecrivant au dessus je crois avoir trouvé une solution.
J'ecris ce que je pense avec mon langage materner c'est à dire VB :

public function iniComosant(ByRef val as System.Window.Form.UserControl ) as Type

'Tableau de Type enfant de MyUserControl
dim MyUCType() as Type
myUCType = System.Reflexion.GetChildrensArrayTypeOf("MyUserControl")

'Je connais pas la reflexion c'est ici que se trouve la difficulté

for each T as Type in MyUCType
if T.equals(val.gettype()) then
val = new [System.Reflexion(T)]
return T
exit for
end if
next

end function

Je sais pas si j'ai été clair, je sais pas non plus si j'ai été possible, mais je passe val par reference, comme ca apres on pourra le recuperer, et la function retourne son type.

Je sais pas si avec la reflexion ca ca etre possible. En tout cas j'aimerais bien avoir un peu de temps, mais je vais pas en avoir d'ici un mois, je profite des mes derniers jours de libre [:'(]

par contre j'ai une question pour coq sur la mini source au dessus. c'est koi la difference entre GetType et TypeOF, TypeOf existe aussi en VB ? j'ai jamais fait de la reflexion, ni meme touché au type donc j'y connais rien, mais j'aimerais bien pouvoir avoir le temps.

Moi je pars dans la reflexion, mais il existe peut etre une autre solution.

@+

Cyril
Messages postés
24
Date d'inscription
lundi 24 février 2003
Statut
Membre
Dernière intervention
28 octobre 2004

Yop all !

Je lis le topic depuis le debut, mais ya une chose qui ne marchera pas (je pense). Dans les exemples donnés, on se base sur le type. Ok mais si val == null, alors on ne peut avoir son type...ou alors j'ai trop mal compris...
Bon sinon je propose tout de meme un debut de proposition.
Elle est a base de Framework 2.0 et generics...

Voici la classe qui va tester et instancier si il faut:
public class Test
{
public T IniComposant<T>(T item ) where T: new()
{
// Test valable uniquement avec des types références.
if (item == null)
{
//MessageBox.Show(item.GetType().ToString());
item = new T();
}
return item;
}
}

Pour tester, voila le Main:
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
UserControl1 uc1 = null;
UserControl2 uc2 = null;

Test test = new Test();
uc1 = test.IniComposant(uc1);
MessageBox.Show(uc1.ClientSize.ToString());

}
}

Avec cette exemple, on a bien uc1 qui vaut null au départ.
Mais la messagebox affiche bien une taille valide ;)

Mission accomplie... javascript:AjoutSmiley(' :big) ');
Messages postés
24
Date d'inscription
lundi 24 février 2003
Statut
Membre
Dernière intervention
28 octobre 2004

Yop, j'ai oublier de dire que uc1 et uc2 sont des classes dérives de UserControl...cela va de soi

Sinon, pour ceux qui s'interessent aux generics, voici une bonne url:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnvs05/html/csharp_generics.asp
Messages postés
6351
Date d'inscription
samedi 1 juin 2002
Statut
Modérateur
Dernière intervention
2 août 2014
92
oui oui bigflo c'est pour ça que j'ai dit que mon exemple ne tenait pas la route, j'avais coder ça a l'arrache en oubliant ce léger détail ^^
et si il est different de null la methode ne sert a rien

en fait plus j'y reflechi et moins je vois l'interet du truc là

Cocoricoooooooo !!!!
Messages postés
41
Date d'inscription
mardi 15 juillet 2003
Statut
Membre
Dernière intervention
7 décembre 2004

Un grand merci bigflo.. seul hic, c'est que je ne peut pas utiliser un framework encore en beta... donc c'est rapé.. je vais chercher du coté des générics..

Pour le type, je me suis rendu compte lors de mes essais que quand la valeur est null, on ne peut pas la recuperer
coq : enfait, ma fonction ini fait un tas de chose (controls de droits entre autre, et je ne voudrais pas le repeter partout dans mon code)

j'ai fait un truc a la barbare cette nuit :
function void ini(ref UserControl ini, UserControl nouv)
{
if(mes_test...)
ini = nouv;
else
nouv.dispose();
}

que j'appel ainsi

ini(mon_control_toto, new toto());

mais faire un new quand on en a pas besoin, c'est limite je trouve... non ?...
Messages postés
6814
Date d'inscription
dimanche 15 décembre 2002
Statut
Modérateur
Dernière intervention
13 octobre 2010
28
l'exemple avec les generic ca à l'air pas mal. j'avais pas non plus pensé que si on regarde le type de null ca allait planté, je m'etais basé sur le code du coq qui etait pas bon :sad)

@+

Cyril
Messages postés
41
Date d'inscription
mardi 15 juillet 2003
Statut
Membre
Dernière intervention
7 décembre 2004

Excelent, ca marche nickel !!

quelque petite correctiobn de fautes de frape et ca donne :

public void load(ref System.Windows.Forms.UserControl t, Type montype)
{
if(mes_testOk(t, montype))
return;
System.Reflection.ConstructorInfo csinfo = montype.GetConstructor(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public, null, System.Reflection.CallingConventions.HasThis, new Type[0], null);
t = (System.Windows.Forms.UserControl) csinfo.Invoke(null);
.....
}
Messages postés
2368
Date d'inscription
mardi 17 avril 2001
Statut
Modérateur
Dernière intervention
26 décembre 2007
20
Deriens ;)

T'en profiteras pour en faire une FAQ ou une mini source :)

::|The S@ib|::
MVP C#.NET
Messages postés
6351
Date d'inscription
samedi 1 juin 2002
Statut
Modérateur
Dernière intervention
2 août 2014
92
effectivement on se prennait trop la tête lol

Cocoricoooooooo !!!!
Messages postés
6814
Date d'inscription
dimanche 15 décembre 2002
Statut
Modérateur
Dernière intervention
13 octobre 2010
28
j'ai rien compris a ce que TheSaib a fait :D mais c'est vrai qu'on devait se prendre un peu la tete, en tout cas ca fait une experience enrichissante de plus :)
reste plus qu'a comprendre la source de TheSaib :big)

Cyril
Messages postés
41
Date d'inscription
mardi 15 juillet 2003
Statut
Membre
Dernière intervention
7 décembre 2004

d'après ce que j'ai compris :

Type montype = typeof(arg); <=== recupère le type de l'object qu'on veut construire
Type[] types = new Type[1]; <=== tableau contenant les types des arguments du constructeur
types[0] = typeokf(int) //arg 1
types[1] = typeof (string) //arg2 <=== ici, on aurait un constructeur du genre new toto(int, string)
object[] param = new object[]; <=== tableau d'object contenant les arguments a passer au constructeur

ConstructotInfo csinfo = monType.GetConstructor(BindingsFlags.Instance | BindingFlags.Public, null, CallingConvention.HasThis, types, null); <=== recupère le constructeur correspondant à (int, string)

csinfo.Invoke(param); <=== Invoke le constructeur avec les parametres...

pour le cas d'un constructeur sans parametres, tu aurait
Type[] types = new Type[0];
et
csinfo.Invoke(null);

....
Messages postés
6814
Date d'inscription
dimanche 15 décembre 2002
Statut
Modérateur
Dernière intervention
13 octobre 2010
28
Merci :)
j'ai meme pas besoin de faire des recherches sur les methodes que je connaissais encore pas :)

@+

Cyril