Rechercher : dans
Par :

Instance d'une classe a partir du nom

Dernière réponse le 24 avr 2009 à 14:09:47 Beetlejuice722, le 28 oct 2008 à 15:06:49 
 Signaler ce message aux modérateurs

Bonjour à tous,

A travers un projet de développement C#, je dispose actuellement d'une classe mère "Article", de sa classe fille "ArticleAcheté" et d'une classe "Program", distincte des 2 autres, celle-ci regroupe l'ensemble des actions possibles (lister, ajouter, modifier, supprimer, rechercher...) applicables sur les enregistrements (articles)

Ainsi, je souhaiterai dans la classe program pouvoir instancier un objet dont la classe serait fournit en paramètre à ma méthode dans une variable string...
--> exemple :
------------------------------------------------------------------
string nomClass = "ArticleAcheté";
static public void LISTER (string nomClass)
{
nomClass toto = new nomClass();
....
}
------------------------------------------------------------------
Ainsi, l'objet "toto" devrait ainsi pouvoir disposer de tout les attributs et methodes spécifiques à la classe fille "ArticleAcheté". De cette manière, on pourrait apeller toutes les methodes de la classe fille "ArticleAcheté" comme ceci :
toto.lecture();
ou encore toto.écriture(); etc...

De toute évidence, la syntaxe ou manière de faire que j'ai employé dans mon "exemple" ne fonctionne pas!

Par conséquent, j'espere que quelqu'un parmi vous pourra m'orienter dans cette réflexion, afin de résoudre ce problème...

Je vous en remercie par avance...

Configuration: Windows Vista
Firefox 3.0.3

Meilleures réponses pour « Instance d'une classe a partir du nom » dans :
Java - Les objets Voir La création d'objets Un objet est une instance de classe, la création d'objets s'appelle donc l'instanciation. Cette instanciation se fait grâce à l'opérateur new suivi du nom de la classe à instancier et de parenthèses contenant les paramètres...
Modifier le label (nom) des partitions. VoirToutes les commandes données ici doivent être effectuées par l'administrateur (en mode root). Donnez des noms les plus simples possibles à vos partitions (si possible seulement des caractères alphanumériques (a...z et 0...9) ainsi que - et _. Ces...
Le mot-clé static ou les attributs et méthodes de classe en POO Voir(NOTE: Cet article explique la signification du mot-clé static au sein d'une classe. La signification de "static" en C n'a par exemple rien à voir.) Vous êtes débutant en programmation orientée objet. En Java, en C++...ou que sais-je encore,...
Les objets en langage C++ VoirLa création d'objets En C++, il existe deux façons de créer des objets, c'est-à-dire d'instancier une classe : de façon statique de façon dynamique La création statique La création statique d'objets consiste à créer un objet en lui affectant un...
Classe et instance d'objet VoirLa notion de classe On appelle classe la structure d'un objet, c'est-à-dire la déclaration de l'ensemble des entités qui composeront un objet. Un objet est donc « issu » d'une classe, c'est le produit qui sort d'un moule. En réalité on dit qu'un...
PHP - Les classes VoirLa notion de classe Php3 intègre un soupçon de caractéristiques empruntées aux langages orientés objet, c'est-à-dire la possibilité d'utiliser des objets, entités regroupant des données et des fonctions au sein d'une structure et rendant la...

1

Beetlejuice722, le 28 oct 2008 à 17:36:24

Personne n'aurait déja rencontré ce problème ?!

Je reste ouvert à toutes suggestions à venir...

Merci

Répondre à Beetlejuice722

2

Marco la baraque, le 28 oct 2008 à 20:51:59

Bonsoir,
Regarde au niveau de l'API de réflexion : http://emerica.developpez.com/dotnet/reflection/introduction­/csharp/

Perso je ne connais absolument pas le C# et je n'ai pas compris grand chose, mais si tu connais un peu le langage ça devrait aller.

Cordialement,

Répondre à Marco la baraque

3

Beetlejuice722, le 28 oct 2008 à 20:53:41

SVP, personne ne s'y connait dans cette notion ?!

mon ami Google m'a dis qu'il fallait mettre en place un principe apellé la "reflection" qui est spécifique aux languages managés...

Je parviens à créer mon objet selon les différentes manières de faire indiqués par des developpeurs, mais dans la mise en oeuvre, mon objet est bien créer, mais il semble ne pas être l'instance de la classe voulue que je lui indique, puiske
les méthodes et attributs de cette classe ne lui sont pas applicables !

Voici donc les différents resultats, je n'ai juska présent pas réussit à mettre en place :

http://www.codyx.org/snippet_instancier-classe-partir-son-nom_95.aspx
http://www.developpez.net/...
http://forum.hardware.fr/...
http://www.generation-nt.com/...

Help me please...

Répondre à Beetlejuice722

4

Beetlejuice722, le 28 oct 2008 à 22:05:52

Merci pour ton aide Marco...

je connais déja ce tuto de developpez.com
Il est bien trop généraliste et effectivement assez compliqué dans le principe à comprendre...

Me concernant, il ne s'agit que de quelques lignes de codes pour permettre la creation d'un objet directement relié aux méthodes et attributs d'une classe fille

Le problème est que l'objet est bien créer mais il ne dispose que de 4 méthodes "génériques" fournient par le compilateur (Equals, getHashCode, getType, toString) qui ne sont en aucun cas spécifique à la classe dont il est question (afficher, get, set, lecture)...

Répondre à Beetlejuice722

5

Marco la baraque, le 28 oct 2008 à 22:32:17

Hello,
Je ne connais pas du tout le C#, mais grosso modo, tes classes sont définies dans des fichiers dll non ?
Du moins c'est ce que je crois comprendre d'après ce que je lis.

Cordialement,

Répondre à Marco la baraque

6

guillaume_74, le 28 oct 2008 à 23:17:13

Je ne connais pas le C#
mais ça ressemble a du Java...
moi moi, ça ne marche pas du tout ton truc c'est normal... c'est pas du tout les mêmes types (après, ptètre des truc a la microsoft... va savoir^^ )
ArticleAchete article;
static public void LISTER (ArticleAchete articl)
{
articl= new ArticleAchete();
....
}

moi, je ne vois que ça de possible... bref^^ je n'ai surement pas comprit ton problème^^

Répondre à guillaume_74

7

Beetlejuice722, le 28 oct 2008 à 23:57:35

En fait, le but de la manoeuvre consiste exactement à déclarer un objet comme tu le fait, sauf que le paramètre en entrée de la méthode doit être une variable string, laquelle contient le nom de la classe pour laquelle sera déclarée l'instance...

cad, le nom de la classe ne doit pas être explicitement nommé, mais plutot contenu dans une chaine de caractère...
ex :
string maClasse = "ArticleAcheté";

static public void (string maClasse)
{
maClasse toto = new maClasse();
}

--> De toute évidence, l'instruction "maClasse toto = new maClasse();" est fausse et ne marche pas, car on ne peut pas convertir implicitement un string en un type (ou class)...

Le but est donc, de créer ou d'instancier un objet d'une classe dont le nom serait fournit dans une variable string (dispo en paramètre de la méthode) !!

Le problème réside uniquement dans la mise en oeuvre...
Ce procédé permet uniquement de rendre les éléments plus "modulaires"...
Imagine que l'on dispose de 100 classe fille pour la classe mère Article (un peu com en framework), cela voudrait dire qu'il faudrait faire autant de méthode lister qu'il y aurait de classe fille !!! Ce n'est pas gérable...

Dans tout les cas, je te suis très reconnaissant pour ton aide et pour ton soutien...
merci beaucoup ! :-)

Répondre à Beetlejuice722

8

choubaka, le 29 oct 2008 à 07:24:39

En java, il existe une méthode "forName("String className), c'est une méthode statque de la classe Class.

mais en C#, jamais vu.

Beau petit challenge

j'ai trouvé ça

http://www.codyx.org/snippet_instancier-classe-partir-son-nom_95.aspx
Chouba,
Rhâââgnagna

Répondre à choubaka

9

Beetlejuice722, le 29 oct 2008 à 11:04:21

Bonjours,

Merci pour ton aide choubaka...

Effectivement, concernant la méthode forName en Java, je n'ai pas retrouvé d'équivalent en C#

Je te remercie également pour le petit tuto que tu m'a donné...
Mais je le connaissaisait déja (voir message 3 de ce topic), je parvient à le mettre en place !

Le problème est que l'objet est bien créer mais il ne dispose que de 4 méthodes "génériques" fournient par le compilateur (Equals, getHashCode, getType, toString) qui ne sont en aucun cas spécifique à la classe dont il est question (afficher, get, set, lecture, etc...) : il s'agit des méthodes que j'ai créer...

Le point obscur dans ce tuto (comme dans tout ceux du message 3), c'est de définir le rôle de l'assembly
Pourtant, je me suis déja documenté sur ce point précis de la "reflection" en C#, mais je ne parvient toujours pas à saisir la manière de faire !

Le but, est d'appeler le bon constructeur de la classe (spécifiée dans la variable string nomClass) passé en paramètre à la méthode, puis de pouvoir invoquer toutes les méthodes de la classe en question, à travers l'objet instancier (de cette même classe)

Le nom de la classe ne doit pas être explicitement nommé dans cette méthode (en dehors d'une variable string, qui lui est fournie en paramètre), car sinon cela impliquerait autant de redondance de code qu'il y aurait d'objet à déclarer pour chaque classe fille !

Une fois de + Merci de votre aide !

Répondre à Beetlejuice722

10

choubaka, le 29 oct 2008 à 14:22:52
Répondre à choubaka

11

Beetlejuice722, le 29 oct 2008 à 19:08:41

Oui mais ici, le problème c'est qu'il faut nommer la classe fille explicitement...

Hors dans mon cas d'utilisation, le nom de la classe à instancier (à travers un objet), doit être contenu dans une variable string...

Si je fait comme dans le lien , j'obtient quelque chose comme :

Class2 c2 = (Class2)Type.GetType("ConsoleApplication1.Class2")....

Hors "Class2" indique et désigne clairement le nom de la classe fille à instancier pour l'objet c2...
Le problème réside justement dans le fait, que le nom ne doit apparaitre que dans une variable string, qui serait fournit en paramètre de la méthode appelante !

J'ai fouiller a plein d'endroit sur Google (developez, csharp, codyx, forum.hardware, génération...)
A chaque fois que c'est le même problème : cad, je me retrouve obligé de lui indiquer le nom de ma classe fille pour que mon objet puisse accéder à ses méthodes et attributs...

En java, ils utilisent une instruction class.forname() pour justement récuperer le contenu d'un string et le convertir...
Mais je ne vois toujours aucun équivalent "direct" en C#

Je suis sur ce problème depuis samedi dernier, et en dépit de ma persévérance, je commence un peu à désespérer...

En tout cas, merci de m'aider Choubaka !

Répondre à Beetlejuice722

12

Marco la baraque, le 29 oct 2008 à 20:19:59

Hello,
Tu as peut-être déjà lu cet article :
http://www.generation-nt.com/...

Je comprends effectivement de ne pas expliciter le type d'objet que tu crées, et pour cela tu dois impérativement utiliser le polymorphisme. La bonne solution est d'utiliser des interfaces (comme le montre cet exemple). De cette manière, le programme est totalement générique et te permet d'instancier toutes les classes qui implémentent ton interface.

"Et pour les autres?". Bah pour les autres, c'est moins évident. Tu peux surement caster ton objet dans une superclasse (par exemple en java tous les objets héritent de Object). Ainsi tu pourras manipuler tous tes objets. L'inconvénient de cette méthode, c'est que pour utiliser les méthodes spécifiques à ton objet, tu devras obligatoirement le downcaster (et donc il te faut connaitre le type de ton instance, en Java ça doit se faire avec obj.getClass()).

Mais bon, en pratique, tu utiliseras pratiquement toujours une interface car si dans ton code tu veux appeler une méthode spécifique, alors cela signifie que tu connais cette méthode, et tu sais que ton objet implémente telle interface (ou étend telle classe).

Cordialement,

Répondre à Marco la baraque

13

mushroom, le 16 mar 2009 à 12:24:53

Tu chercherais pas tout simplement un truc du genre par hasard? C'est un petit extrait de ma classe Core...

private function includeModel($file)
{
$class = ucfirst($file);
$path = root .'model/'. $class .'.php';

if(file_exists($path))
{
require_once($path);
$Object = new $class();
$action = $this->vars['action'];
$Object->$action();
return true;
}
else return false;
}

Répondre à mushroom

14

Otaku 54, le 20 mar 2009 à 11:20:04

Salut a tous :)

Je tenais a savoir si tu avais résolu ton problème BeetleJuice722 car je suis dans le même cas que toi pour un de mes projets. Après avoir errer sur le net pendant des heures, je n'ai toujours pas trouvé de solutions :s

Si tu n'as pas réussi, comment l'a tu esquivé ? :)

Merci d'avance de ta réponse ;)

Répondre à Otaku 54

16

Smashingraph, le 20 avr 2009 à 16:56:04

Bonjour à tous,

Je vois qu'il n'y a pas eu de réponses claires sur la question.

Pour créer un objet à l'aide la reflection, c'est très simple, tu récupères l'objet assembly, puis tu invoques "CreateInstance". A l'aide du nom de la classe et du tableau de paramètres passés (pour les arguments du constructeur), tu reçois un objet instancié de la classe voulue.

Voici ci-dessous 3 méthodes qui permettent d'effectuer ce traitement (la troisième est celle qui appelle "CreateInstance" sur l'objet Assembly):

1) Cette méthode récupère l'objet assembly de celle qui est en cours d'exécution. Typiquement si cette méthode se trouve dans une libraire externe à ton programme principal, l'assembly appelante (CallingAssembly) est la libraire externe, et donc cette méthode va instancier un objet d'une classe se trouvant dans la librairie externe. Elle appelle ensuite la méthode "CreateObject", troisième méthode ci-dessous.

public static object CreateObjectWithExecutingAssembly(string sClassName, object[] args)
{
    System.Reflection.Assembly oAssembly = System.Reflection.Assembly.GetExecutingAssembly();
     return CreateObject(sClassName, oAssembly, args);
}


2) Cette méthode récupère l'objet assembly de celle qui appelle cette methode. Typiquement si cette méthode se trouve dans une libraire externe à ton programme principal, l'assembly appelante (CallingAssembly) est
le programme principal, et donc cette méthode va instancier un objet d'une classe se trouvant dans ton programme principal (Partant du principe que ta librairie externe n'as aucune référence sur le programme principal). Elle appelle ensuite la méthode "CreateObject", troisième méthode ci-dessous.
 
public static object CreateObjectWithCallingAssembly(string sClassName, object[] args )
{
    System.Reflection.Assembly oAssembly = System.Reflection.Assembly.GetCallingAssembly();
    return CreateObject(sClassName, oAssembly, args);
}



3) Cette méthode va instancier un nouvel objet à l'aide de la String "sClassName" passée en paramètre. Les arguments correspondent à la signature du constructeur de la classe, à savoir les paramètres qu'il faut passer au constructeur.
public static object CreateObject(string sClassName,  System.Reflection.Assembly oAssembly, object[] args )
{
    return oAssembly.CreateInstance(sClassName, true, System.Reflection.BindingFlags.CreateInstance, null, args, null, null);
}


Ensuite, que faire avec cette objet ? Si on sait de quelle nature il doit être, il suffit de le caster dans l'objet voulu:
MaClasse oMaClasse = (MaClasse) objetInstancié;


Par contre si on ne connaît pas la nature de la classe, et qu'on a les méthode que l'on désire appeller sur cet objet sous forme de String (pour une application totalement dynamique, dont les indications sont écrites dans un fichier xml par exemple) il va falloir opérer comme ceci:

        public static object GetMethodObjectResult(object oUnderlyingObject, string sMethod, object[] oParams)
        {
            object oResult = null;
            System.Reflection.MethodInfo oMethodInfo = null;
            try
            {
                if (oUnderlyingObject != null)
                {
                    System.Type dynClassType = oUnderlyingObject.GetType();
                    if (sMethod != null && sMethod != "")
                    {
                        oMethodInfo = dynClassType.GetMethod(sMethod);
                        if (oMethodInfo != null)
                        {
                            oResult = oMethodInfo.Invoke(oUnderlyingObject, oParams);
                        }
                    }
                }
            }
            catch (Exception e)
            {
                // Exception à traiter au cas par cas
            }
            return oResult;
        }


Il ne reste plus qu'à traiter la réponse de la méthode, qui est sous forme d'un objet à caster selon le type.

Voilà j'espère avoir été plus ou moins clair, et j'espère que cela a pu éclairer certaines personnes.

Bonne fin de journée,

Répondre à Smashingraph

17

MasterTnT, le 24 avr 2009 à 14:07:20
  • +2

Type lObjType = Type.GetType("MaClasseACreer");
if
(lObjType != null)
{
Object lObject = Activator.CreateInstance(lObjType);
if
(lCmd != null)
{
....................................
}
}

Répondre à MasterTnT

18

 MasterTnT, le 24 avr 2009 à 14:09:47

Il faut remplacer lCmd != null par lObject != null

Répondre à MasterTnT

15

guillaume_74, le 19 avr 2009 à 02:14:19

Si t'es en .NET
ya la méthode "CallByName"

sinon...
lol la réflection! ca existe dans tout les langage ( dans les IDE, c'est ce qui permet l'intellisense: quand tu tape sur '.' ca te met des methode et tout et tout...)

Répondre à guillaume_74