Voil=E0, j'ai trouv=E9 sur le site de developpez.com une introduction =E0
la reflexion en C#. M=EAme si je comprends bien le principe du
m=E9canisme de la r=E9flexion, je bute sur un exemple de l'article. Le
voici :
using System;
namespace GenericAutomobile {
public interface IAutomobile {
void Accelerer(double dIncrement);
void Tourner(double dAngle);
}
}
Le programme principal est charg=E9 de d=E9couvrir et d'instancier un
objet de type AudiRS4 ou BmwM3. Pour ce faire, il lui faut
imp=E9rativement une r=E9f=E9rence sur l'assemblage IAutomobile.dll.
Ensuite, il suffira de renseigner l'application sur le nom du type que
l'on veut cr=E9er, de parcourir les assemblages et de voir si le type
demand=E9 est bel et bien pr=E9sent.
Instanciation d'un type
// Objet r=E9alisant notre interface
IAutomobile Automobile;
// Nom de l'objet =E0 cr=E9er
string m_sClassName =3D "AudiRS4";
// Chargement de l'assemblage
Assembly assembly =3D Assembly.LoadFrom(m_sClassName + ".dll");
// Introspection des types
foreach(Type type in assembly.GetTypes()) {
if(m_sClassName =3D=3D type.Name) {
// Un type correspond, cr=E9ation d'un objet
Automobile =3D (GenericAutomobile.IAutomobile)
Activator.CreateInstance(type);
}
}
foreach(Type type in assembly.GetTypes()) { if(m_sClassName == type.Name) { // Un type correspond, création d'un objet Automobile = (GenericAutomobile.IAutomobile) Activator.CreateInstance(type); } }
Ce que je ne comprends pas bien dans cet exemple c'est pourquoi on doit faire un cast (GenericAutomobile.IAutomobile)
On se retrouve donc avec un objet IAutomobile et non pas un objet AudiRS4. Je me perds un peu ...
Vous avez tous à fait raison dans votre analyse mais il faut pousser le raisonnement un peu plus loin.
Vous avez donc un objet de classe "AudiRS4" qui implémente "GenericAutomobile.IAutomobile", ce qui veut dire que vous aves un objet que vous pouvez manipuler comme n'import quelle voiture, même celles qui n'existe pas à la compilation de l'assembly.
Le jour où un nouveau modèle (classe) de voiture est crée, vous n'aurais pas à recompiler votre exécutable pour prendre en compte ce nouveau modèle car vous n'aurais cas le spécifié dans la ligne de commande ou dans le fichier de configuration ou par une recherche dans l'ensemble des types d'une liste d'assemblies modifiables dynamiquement.
Si vous utilisez dans votre code la classe "AudiRS4" (pas la chaîne de caractère), vous devez déjà l'avoir développer dans un assembly et vous ne pourrais pas instancier de "Logan" après avoir compilé votre assembly.
Je pense que vous devez étudier l'intérêt des interfaces, par oppositions aux classes de bases, avant de vous lancez dans la réflexion.
foreach(Type type in assembly.GetTypes()) {
if(m_sClassName == type.Name) {
// Un type correspond, création d'un objet
Automobile = (GenericAutomobile.IAutomobile)
Activator.CreateInstance(type);
}
}
Ce que je ne comprends pas bien dans cet exemple c'est pourquoi on doit
faire un cast (GenericAutomobile.IAutomobile)
On se retrouve donc avec un objet IAutomobile et non pas un objet
AudiRS4. Je me perds un peu ...
Vous avez tous à fait raison dans votre analyse mais il faut pousser le
raisonnement un peu plus loin.
Vous avez donc un objet de classe "AudiRS4" qui implémente
"GenericAutomobile.IAutomobile", ce qui veut dire que vous aves un objet que
vous pouvez manipuler comme n'import quelle voiture, même celles qui
n'existe pas à la compilation de l'assembly.
Le jour où un nouveau modèle (classe) de voiture est crée, vous n'aurais pas
à recompiler votre exécutable pour prendre en compte ce nouveau modèle car
vous n'aurais cas le spécifié dans la ligne de commande ou dans le fichier
de configuration ou par une recherche dans l'ensemble des types d'une liste
d'assemblies modifiables dynamiquement.
Si vous utilisez dans votre code la classe "AudiRS4" (pas la chaîne de
caractère), vous devez déjà l'avoir développer dans un assembly et vous ne
pourrais pas instancier de "Logan" après avoir compilé votre assembly.
Je pense que vous devez étudier l'intérêt des interfaces, par oppositions
aux classes de bases, avant de vous lancez dans la réflexion.
foreach(Type type in assembly.GetTypes()) { if(m_sClassName == type.Name) { // Un type correspond, création d'un objet Automobile = (GenericAutomobile.IAutomobile) Activator.CreateInstance(type); } }
Ce que je ne comprends pas bien dans cet exemple c'est pourquoi on doit faire un cast (GenericAutomobile.IAutomobile)
On se retrouve donc avec un objet IAutomobile et non pas un objet AudiRS4. Je me perds un peu ...
Vous avez tous à fait raison dans votre analyse mais il faut pousser le raisonnement un peu plus loin.
Vous avez donc un objet de classe "AudiRS4" qui implémente "GenericAutomobile.IAutomobile", ce qui veut dire que vous aves un objet que vous pouvez manipuler comme n'import quelle voiture, même celles qui n'existe pas à la compilation de l'assembly.
Le jour où un nouveau modèle (classe) de voiture est crée, vous n'aurais pas à recompiler votre exécutable pour prendre en compte ce nouveau modèle car vous n'aurais cas le spécifié dans la ligne de commande ou dans le fichier de configuration ou par une recherche dans l'ensemble des types d'une liste d'assemblies modifiables dynamiquement.
Si vous utilisez dans votre code la classe "AudiRS4" (pas la chaîne de caractère), vous devez déjà l'avoir développer dans un assembly et vous ne pourrais pas instancier de "Logan" après avoir compilé votre assembly.
Je pense que vous devez étudier l'intérêt des interfaces, par oppositions aux classes de bases, avant de vous lancez dans la réflexion.
-- Paul Bacelar
fragmonster
D'accord, merci. Cependant, je me trompe peut-être, mais si on passe par une interface et qu'à la fin du processus d'instanciation dynamique on se retrouve avec un objet de type IAutomobile, on perd une partie des possibilités qu'on aurait eu avec un objet AudiRS4 ou BMW. Je m'explique : Dans l'interface, on ne déclare que des méthodes. Par conséquent si on a besoin d'utiliser des accesseurs on est coincé. Celà dit on peut contourner le pb en passant par une méthode.
N'y a t-il aucun moyen de se retrouve au final avec un objet de type AudiRS4, plutôt qu'une Interface?
Bref, je trouve le principe de la reflexion et de la liaison tardive très bien. Je travaille sur un projet dans lequel je risque d'en avoir besoin. Encore faut-il savoir l'utiliser intelligemment.
D'accord, merci. Cependant, je me trompe peut-être, mais si on passe
par une interface et qu'à la fin du processus d'instanciation
dynamique on se retrouve avec un objet de type IAutomobile, on perd une
partie des possibilités qu'on aurait eu avec un objet AudiRS4 ou BMW.
Je m'explique : Dans l'interface, on ne déclare que des méthodes. Par
conséquent si on a besoin d'utiliser des accesseurs on est coincé.
Celà dit on peut contourner le pb en passant par une méthode.
N'y a t-il aucun moyen de se retrouve au final avec un objet de type
AudiRS4, plutôt qu'une Interface?
Bref, je trouve le principe de la reflexion et de la liaison tardive
très bien. Je travaille sur un projet dans lequel je risque d'en avoir
besoin. Encore faut-il savoir l'utiliser intelligemment.
D'accord, merci. Cependant, je me trompe peut-être, mais si on passe par une interface et qu'à la fin du processus d'instanciation dynamique on se retrouve avec un objet de type IAutomobile, on perd une partie des possibilités qu'on aurait eu avec un objet AudiRS4 ou BMW. Je m'explique : Dans l'interface, on ne déclare que des méthodes. Par conséquent si on a besoin d'utiliser des accesseurs on est coincé. Celà dit on peut contourner le pb en passant par une méthode.
N'y a t-il aucun moyen de se retrouve au final avec un objet de type AudiRS4, plutôt qu'une Interface?
Bref, je trouve le principe de la reflexion et de la liaison tardive très bien. Je travaille sur un projet dans lequel je risque d'en avoir besoin. Encore faut-il savoir l'utiliser intelligemment.
Fabien Bezagu
> "fragmonster" a écrit dans le message de news:
Dans l'interface, on ne déclare que des méthodes. Par conséquent si on a besoin d'utiliser des accesseurs on est coincé.
C'est faux, et à partir de là, ta démonstration l'est aussi....
> "fragmonster" <fmeriot@gmail.com> a écrit dans le message de news:
Dans l'interface, on ne déclare que des méthodes. Par
conséquent si on a besoin d'utiliser des accesseurs on est coincé.
C'est faux, et à partir de là, ta démonstration l'est aussi....
Dans l'interface, on ne déclare que des méthodes. Par conséquent si on a besoin d'utiliser des accesseurs on est coincé.
C'est faux, et à partir de là, ta démonstration l'est aussi....
Zoury
> N'y a t-il aucun moyen de se retrouve au final avec un objet de type AudiRS4, plutôt qu'une Interface?
Certes ! L'exemple fait exactement cela, sauf qu'il cast le résultat en IAutomobile afin de permettre de travailler directement avec les méthodes de l'interface. Il te suffit de ne *pas* le caster.
Ex : //*** // Notre voiture AudiRS4 AudiRS4 audi; // Nom de l'objet à créer string m_sClassName = "AudiRS4"; // Chargement de l'assemblage Assembly assembly = Assembly.LoadFrom(m_sClassName + ".dll"); // Introspection des types foreach(Type type in assembly.GetTypes()) { if(m_sClassName == type.Name) { // Un type correspond, création d'un objet audi = Activator.CreateInstance(type); } } //***
ainsi, ta variable "audi" pointe sur un objet de type AudiRS4 comme tu le souhaitais.
-- Cordialement Yanick MVP pour Visual Basic
> N'y a t-il aucun moyen de se retrouve au final avec un objet de type
AudiRS4, plutôt qu'une Interface?
Certes ! L'exemple fait exactement cela, sauf qu'il cast le résultat en
IAutomobile afin de permettre de travailler directement avec les méthodes de
l'interface.
Il te suffit de ne *pas* le caster.
Ex :
//***
// Notre voiture AudiRS4
AudiRS4 audi;
// Nom de l'objet à créer
string m_sClassName = "AudiRS4";
// Chargement de l'assemblage
Assembly assembly = Assembly.LoadFrom(m_sClassName + ".dll");
// Introspection des types
foreach(Type type in assembly.GetTypes()) {
if(m_sClassName == type.Name) {
// Un type correspond, création d'un objet
audi = Activator.CreateInstance(type);
}
}
//***
ainsi, ta variable "audi" pointe sur un objet de type AudiRS4 comme tu le
souhaitais.
> N'y a t-il aucun moyen de se retrouve au final avec un objet de type AudiRS4, plutôt qu'une Interface?
Certes ! L'exemple fait exactement cela, sauf qu'il cast le résultat en IAutomobile afin de permettre de travailler directement avec les méthodes de l'interface. Il te suffit de ne *pas* le caster.
Ex : //*** // Notre voiture AudiRS4 AudiRS4 audi; // Nom de l'objet à créer string m_sClassName = "AudiRS4"; // Chargement de l'assemblage Assembly assembly = Assembly.LoadFrom(m_sClassName + ".dll"); // Introspection des types foreach(Type type in assembly.GetTypes()) { if(m_sClassName == type.Name) { // Un type correspond, création d'un objet audi = Activator.CreateInstance(type); } } //***
ainsi, ta variable "audi" pointe sur un objet de type AudiRS4 comme tu le souhaitais.
-- Cordialement Yanick MVP pour Visual Basic
Fabien Bezagu
J'insiste, quitte à être lourd, que cet exemple n'a absolument aucun intérêt !
Fabien
"Zoury" <yanick_lefebvre at hotmail dot com> a écrit dans le message de news: %
N'y a t-il aucun moyen de se retrouve au final avec un objet de type AudiRS4, plutôt qu'une Interface?
Certes ! L'exemple fait exactement cela, sauf qu'il cast le résultat en IAutomobile afin de permettre de travailler directement avec les méthodes de l'interface. Il te suffit de ne *pas* le caster.
Ex : //*** // Notre voiture AudiRS4 AudiRS4 audi; // Nom de l'objet à créer string m_sClassName = "AudiRS4"; // Chargement de l'assemblage Assembly assembly = Assembly.LoadFrom(m_sClassName + ".dll"); // Introspection des types foreach(Type type in assembly.GetTypes()) { if(m_sClassName == type.Name) { // Un type correspond, création d'un objet audi = Activator.CreateInstance(type); } } //***
ainsi, ta variable "audi" pointe sur un objet de type AudiRS4 comme tu le souhaitais.
-- Cordialement Yanick MVP pour Visual Basic
J'insiste, quitte à être lourd, que cet exemple n'a absolument aucun intérêt
!
Fabien
"Zoury" <yanick_lefebvre at hotmail dot com> a écrit dans le message de
news: %23RsOsUIuFHA.1264@TK2MSFTNGP12.phx.gbl...
N'y a t-il aucun moyen de se retrouve au final avec un objet de type
AudiRS4, plutôt qu'une Interface?
Certes ! L'exemple fait exactement cela, sauf qu'il cast le résultat en
IAutomobile afin de permettre de travailler directement avec les méthodes
de l'interface.
Il te suffit de ne *pas* le caster.
Ex :
//***
// Notre voiture AudiRS4
AudiRS4 audi;
// Nom de l'objet à créer
string m_sClassName = "AudiRS4";
// Chargement de l'assemblage
Assembly assembly = Assembly.LoadFrom(m_sClassName + ".dll");
// Introspection des types
foreach(Type type in assembly.GetTypes()) {
if(m_sClassName == type.Name) {
// Un type correspond, création d'un objet
audi = Activator.CreateInstance(type);
}
}
//***
ainsi, ta variable "audi" pointe sur un objet de type AudiRS4 comme tu le
souhaitais.
J'insiste, quitte à être lourd, que cet exemple n'a absolument aucun intérêt !
Fabien
"Zoury" <yanick_lefebvre at hotmail dot com> a écrit dans le message de news: %
N'y a t-il aucun moyen de se retrouve au final avec un objet de type AudiRS4, plutôt qu'une Interface?
Certes ! L'exemple fait exactement cela, sauf qu'il cast le résultat en IAutomobile afin de permettre de travailler directement avec les méthodes de l'interface. Il te suffit de ne *pas* le caster.
Ex : //*** // Notre voiture AudiRS4 AudiRS4 audi; // Nom de l'objet à créer string m_sClassName = "AudiRS4"; // Chargement de l'assemblage Assembly assembly = Assembly.LoadFrom(m_sClassName + ".dll"); // Introspection des types foreach(Type type in assembly.GetTypes()) { if(m_sClassName == type.Name) { // Un type correspond, création d'un objet audi = Activator.CreateInstance(type); } } //***
ainsi, ta variable "audi" pointe sur un objet de type AudiRS4 comme tu le souhaitais.
-- Cordialement Yanick MVP pour Visual Basic
Arnaud Debaene
fragmonster wrote:
D'accord, merci. Cependant, je me trompe peut-être, mais si on passe par une interface et qu'à la fin du processus d'instanciation dynamique on se retrouve avec un objet de type IAutomobile, on perd une partie des possibilités qu'on aurait eu avec un objet AudiRS4 ou BMW. Je m'explique : Dans l'interface, on ne déclare que des méthodes. Par conséquent si on a besoin d'utiliser des accesseurs on est coincé. Celà dit on peut contourner le pb en passant par une méthode.
On peut déclarer des accesseurs dans une interface.... (au bout du compte, les accesseurs ne sont que des fonctions avec un peu de sucre syntaxique autour)
N'y a t-il aucun moyen de se retrouve au final avec un objet de type AudiRS4, plutôt qu'une Interface?
Bien sûr qu'on peut le faire, mais on perd tous l'intérêt du polymorphisme et de la liaison tardive. L'intérêt essentiel (unique?) de ce genre de programmation, c'est de faire des plugins, c'est-à-dire que tu écrits le programme principal qui manipule des IAutomobile, et quelqu'un d'autre (un client, un parfais inconnu qui utilise ton programme) peut lui rajouter des extensions en programmant les classes AudiRS4, BmwM3 ou ce que tu veux. Dans le programme principal, *tu ne sais même pas* que ces classes existent. Les différentesmodules communiquent entre eux via l'interface commune (IAutomobile) sans rien savoir sur l'implémentation des autres modules. La subtilité ensuite consiste à définir correctement les interfaces (IAutomobile) pour que les plugins (Audi, BMW, etc...) puisent faire tout ce qu'ils veulent dans le cadre de cette interface.
Arnaud MVP - VC
fragmonster wrote:
D'accord, merci. Cependant, je me trompe peut-être, mais si on passe
par une interface et qu'à la fin du processus d'instanciation
dynamique on se retrouve avec un objet de type IAutomobile, on perd
une partie des possibilités qu'on aurait eu avec un objet AudiRS4 ou
BMW. Je m'explique : Dans l'interface, on ne déclare que des
méthodes. Par conséquent si on a besoin d'utiliser des accesseurs on
est coincé. Celà dit on peut contourner le pb en passant par une
méthode.
On peut déclarer des accesseurs dans une interface.... (au bout du compte,
les accesseurs ne sont que des fonctions avec un peu de sucre syntaxique
autour)
N'y a t-il aucun moyen de se retrouve au final avec un objet de type
AudiRS4, plutôt qu'une Interface?
Bien sûr qu'on peut le faire, mais on perd tous l'intérêt du polymorphisme
et de la liaison tardive. L'intérêt essentiel (unique?) de ce genre de
programmation, c'est de faire des plugins, c'est-à-dire que tu écrits le
programme principal qui manipule des IAutomobile, et quelqu'un d'autre (un
client, un parfais inconnu qui utilise ton programme) peut lui rajouter des
extensions en programmant les classes AudiRS4, BmwM3 ou ce que tu veux. Dans
le programme principal, *tu ne sais même pas* que ces classes existent. Les
différentesmodules communiquent entre eux via l'interface commune
(IAutomobile) sans rien savoir sur l'implémentation des autres modules.
La subtilité ensuite consiste à définir correctement les interfaces
(IAutomobile) pour que les plugins (Audi, BMW, etc...) puisent faire tout ce
qu'ils veulent dans le cadre de cette interface.
D'accord, merci. Cependant, je me trompe peut-être, mais si on passe par une interface et qu'à la fin du processus d'instanciation dynamique on se retrouve avec un objet de type IAutomobile, on perd une partie des possibilités qu'on aurait eu avec un objet AudiRS4 ou BMW. Je m'explique : Dans l'interface, on ne déclare que des méthodes. Par conséquent si on a besoin d'utiliser des accesseurs on est coincé. Celà dit on peut contourner le pb en passant par une méthode.
On peut déclarer des accesseurs dans une interface.... (au bout du compte, les accesseurs ne sont que des fonctions avec un peu de sucre syntaxique autour)
N'y a t-il aucun moyen de se retrouve au final avec un objet de type AudiRS4, plutôt qu'une Interface?
Bien sûr qu'on peut le faire, mais on perd tous l'intérêt du polymorphisme et de la liaison tardive. L'intérêt essentiel (unique?) de ce genre de programmation, c'est de faire des plugins, c'est-à-dire que tu écrits le programme principal qui manipule des IAutomobile, et quelqu'un d'autre (un client, un parfais inconnu qui utilise ton programme) peut lui rajouter des extensions en programmant les classes AudiRS4, BmwM3 ou ce que tu veux. Dans le programme principal, *tu ne sais même pas* que ces classes existent. Les différentesmodules communiquent entre eux via l'interface commune (IAutomobile) sans rien savoir sur l'implémentation des autres modules. La subtilité ensuite consiste à définir correctement les interfaces (IAutomobile) pour que les plugins (Audi, BMW, etc...) puisent faire tout ce qu'ils veulent dans le cadre de cette interface.
Arnaud MVP - VC
Faust
/_fragmonster_ a émis l'idée suivante/ :
D'accord, merci. Cependant, je me trompe peut-être, mais si on passe par une interface et qu'à la fin du processus d'instanciation dynamique on se retrouve avec un objet de type IAutomobile, on perd une partie des possibilités qu'on aurait eu avec un objet AudiRS4 ou BMW. Je m'explique : Dans l'interface, on ne déclare que des méthodes. Par conséquent si on a besoin d'utiliser des accesseurs on est coincé. Celà dit on peut contourner le pb en passant par une méthode.
N'y a t-il aucun moyen de se retrouve au final avec un objet de type AudiRS4, plutôt qu'une Interface?
non ça ne ferait qu'allourdir ton programme: comme le disait Paul, cela supposerait que ton programme connait la classe (ainsi que toutes celles qu'il pourrait être amené à utiliser) et qu'il soit recompilé à chaque modification de la classe ou création d'une nouvelle classe
l'utilisation d'interfaces te permet de passer outre ce problème
si ton objet "AudiRS4" doit fournir d'autre méthodes qui lui sont spécifiques, il doit le faire au travers d'autres interfaces (qui pourront eventuellement être utilisées dans d'autres classes)
c'est la seule solution propre
ou alors, une autre possibilité est d'utiliser une classe parente qui servirait de base à "AudiRS4" mais au final, on retrouve la même limitation qu'avec les interfaces: les méthodes spécifiques de ta classe seront inconnues du programme. Par contre, tu perdrais la possibilité de les faire connaitre comme le permettrait l'implémentation d'une deuxième interface
le passage par la réflexion pourrait te permettre de découvrir les fonctions/méthodes spécifiques de ta classe mais c'est une solution bien lourde comparativement aux interfaces pour au final avoir exactement le même résultat (puisque ça obligerait à avoir les dites fonctions avec un nom particulier, avec une liste de paramètres bien précis)
Pour te donner une idée, sur un projet particulièrement touffu, j'ai des objets qui implementent jusqu'à une dizaines d'interfaces (ça pourrait même être plus mais j'ai préféré limiter pour faciliter la maintenance du code)
-- */Teträm/* http://www.tetram.org
"Avale tout sans réfléchir, ce qui n'est pas commestible resortira toujours" - Proverbe Troll
/_fragmonster_ a émis l'idée suivante/ :
D'accord, merci. Cependant, je me trompe peut-être, mais si on passe
par une interface et qu'à la fin du processus d'instanciation
dynamique on se retrouve avec un objet de type IAutomobile, on perd une
partie des possibilités qu'on aurait eu avec un objet AudiRS4 ou BMW.
Je m'explique : Dans l'interface, on ne déclare que des méthodes. Par
conséquent si on a besoin d'utiliser des accesseurs on est coincé.
Celà dit on peut contourner le pb en passant par une méthode.
N'y a t-il aucun moyen de se retrouve au final avec un objet de type
AudiRS4, plutôt qu'une Interface?
non ça ne ferait qu'allourdir ton programme: comme le disait Paul, cela
supposerait que ton programme connait la classe (ainsi que toutes
celles qu'il pourrait être amené à utiliser) et qu'il soit recompilé à
chaque modification de la classe ou création d'une nouvelle classe
l'utilisation d'interfaces te permet de passer outre ce problème
si ton objet "AudiRS4" doit fournir d'autre méthodes qui lui sont
spécifiques, il doit le faire au travers d'autres interfaces (qui
pourront eventuellement être utilisées dans d'autres classes)
c'est la seule solution propre
ou alors, une autre possibilité est d'utiliser une classe parente qui
servirait de base à "AudiRS4" mais au final, on retrouve la même
limitation qu'avec les interfaces: les méthodes spécifiques de ta
classe seront inconnues du programme. Par contre, tu perdrais la
possibilité de les faire connaitre comme le permettrait
l'implémentation d'une deuxième interface
le passage par la réflexion pourrait te permettre de découvrir les
fonctions/méthodes spécifiques de ta classe mais c'est une solution
bien lourde comparativement aux interfaces pour au final avoir
exactement le même résultat (puisque ça obligerait à avoir les dites
fonctions avec un nom particulier, avec une liste de paramètres bien
précis)
Pour te donner une idée, sur un projet particulièrement touffu, j'ai
des objets qui implementent jusqu'à une dizaines d'interfaces (ça
pourrait même être plus mais j'ai préféré limiter pour faciliter la
maintenance du code)
--
*/Teträm/*
http://www.tetram.org
"Avale tout sans réfléchir, ce qui n'est pas commestible resortira
toujours" - Proverbe Troll
D'accord, merci. Cependant, je me trompe peut-être, mais si on passe par une interface et qu'à la fin du processus d'instanciation dynamique on se retrouve avec un objet de type IAutomobile, on perd une partie des possibilités qu'on aurait eu avec un objet AudiRS4 ou BMW. Je m'explique : Dans l'interface, on ne déclare que des méthodes. Par conséquent si on a besoin d'utiliser des accesseurs on est coincé. Celà dit on peut contourner le pb en passant par une méthode.
N'y a t-il aucun moyen de se retrouve au final avec un objet de type AudiRS4, plutôt qu'une Interface?
non ça ne ferait qu'allourdir ton programme: comme le disait Paul, cela supposerait que ton programme connait la classe (ainsi que toutes celles qu'il pourrait être amené à utiliser) et qu'il soit recompilé à chaque modification de la classe ou création d'une nouvelle classe
l'utilisation d'interfaces te permet de passer outre ce problème
si ton objet "AudiRS4" doit fournir d'autre méthodes qui lui sont spécifiques, il doit le faire au travers d'autres interfaces (qui pourront eventuellement être utilisées dans d'autres classes)
c'est la seule solution propre
ou alors, une autre possibilité est d'utiliser une classe parente qui servirait de base à "AudiRS4" mais au final, on retrouve la même limitation qu'avec les interfaces: les méthodes spécifiques de ta classe seront inconnues du programme. Par contre, tu perdrais la possibilité de les faire connaitre comme le permettrait l'implémentation d'une deuxième interface
le passage par la réflexion pourrait te permettre de découvrir les fonctions/méthodes spécifiques de ta classe mais c'est une solution bien lourde comparativement aux interfaces pour au final avoir exactement le même résultat (puisque ça obligerait à avoir les dites fonctions avec un nom particulier, avec une liste de paramètres bien précis)
Pour te donner une idée, sur un projet particulièrement touffu, j'ai des objets qui implementent jusqu'à une dizaines d'interfaces (ça pourrait même être plus mais j'ai préféré limiter pour faciliter la maintenance du code)
-- */Teträm/* http://www.tetram.org
"Avale tout sans réfléchir, ce qui n'est pas commestible resortira toujours" - Proverbe Troll
Paul Bacelar
Au que si, car si tu ne castes pas, et utilises un objet de type AudiRS4, il te faut avoir une référence à la compilation sur l'assembly contenant le type "AudiRS4".
Si tu fais cela, faire de la réflexion tient plus du pignolage intellectuel qu'à la résolution d'un problème concret car tu n'en tireras aucun avantage.
-- Paul Bacelar
"Fabien Bezagu" <fbezagu_at_novacor_dot_fr> wrote in message news:
J'insiste, quitte à être lourd, que cet exemple n'a absolument aucun
intérêt
!
Fabien
"Zoury" <yanick_lefebvre at hotmail dot com> a écrit dans le message de news: % >> N'y a t-il aucun moyen de se retrouve au final avec un objet de type >> AudiRS4, plutôt qu'une Interface? > > Certes ! L'exemple fait exactement cela, sauf qu'il cast le résultat en > IAutomobile afin de permettre de travailler directement avec les
méthodes
> de l'interface. > Il te suffit de ne *pas* le caster. > > Ex : > //*** > // Notre voiture AudiRS4 > AudiRS4 audi; > // Nom de l'objet à créer > string m_sClassName = "AudiRS4"; > // Chargement de l'assemblage > Assembly assembly = Assembly.LoadFrom(m_sClassName + ".dll"); > // Introspection des types > foreach(Type type in assembly.GetTypes()) { > if(m_sClassName == type.Name) { > // Un type correspond, création d'un objet > audi = Activator.CreateInstance(type); > } > } > //*** > > ainsi, ta variable "audi" pointe sur un objet de type AudiRS4 comme tu
Au que si, car si tu ne castes pas, et utilises un objet de type AudiRS4, il
te faut avoir une référence à la compilation sur l'assembly contenant le
type "AudiRS4".
Si tu fais cela, faire de la réflexion tient plus du pignolage intellectuel
qu'à la résolution d'un problème concret car tu n'en tireras aucun avantage.
--
Paul Bacelar
"Fabien Bezagu" <fbezagu_at_novacor_dot_fr> wrote in message
news:etKkJxIuFHA.3684@TK2MSFTNGP09.phx.gbl...
J'insiste, quitte à être lourd, que cet exemple n'a absolument aucun
intérêt
!
Fabien
"Zoury" <yanick_lefebvre at hotmail dot com> a écrit dans le message de
news: %23RsOsUIuFHA.1264@TK2MSFTNGP12.phx.gbl...
>> N'y a t-il aucun moyen de se retrouve au final avec un objet de type
>> AudiRS4, plutôt qu'une Interface?
>
> Certes ! L'exemple fait exactement cela, sauf qu'il cast le résultat en
> IAutomobile afin de permettre de travailler directement avec les
méthodes
> de l'interface.
> Il te suffit de ne *pas* le caster.
>
> Ex :
> //***
> // Notre voiture AudiRS4
> AudiRS4 audi;
> // Nom de l'objet à créer
> string m_sClassName = "AudiRS4";
> // Chargement de l'assemblage
> Assembly assembly = Assembly.LoadFrom(m_sClassName + ".dll");
> // Introspection des types
> foreach(Type type in assembly.GetTypes()) {
> if(m_sClassName == type.Name) {
> // Un type correspond, création d'un objet
> audi = Activator.CreateInstance(type);
> }
> }
> //***
>
> ainsi, ta variable "audi" pointe sur un objet de type AudiRS4 comme tu
Au que si, car si tu ne castes pas, et utilises un objet de type AudiRS4, il te faut avoir une référence à la compilation sur l'assembly contenant le type "AudiRS4".
Si tu fais cela, faire de la réflexion tient plus du pignolage intellectuel qu'à la résolution d'un problème concret car tu n'en tireras aucun avantage.
-- Paul Bacelar
"Fabien Bezagu" <fbezagu_at_novacor_dot_fr> wrote in message news:
J'insiste, quitte à être lourd, que cet exemple n'a absolument aucun
intérêt
!
Fabien
"Zoury" <yanick_lefebvre at hotmail dot com> a écrit dans le message de news: % >> N'y a t-il aucun moyen de se retrouve au final avec un objet de type >> AudiRS4, plutôt qu'une Interface? > > Certes ! L'exemple fait exactement cela, sauf qu'il cast le résultat en > IAutomobile afin de permettre de travailler directement avec les
méthodes
> de l'interface. > Il te suffit de ne *pas* le caster. > > Ex : > //*** > // Notre voiture AudiRS4 > AudiRS4 audi; > // Nom de l'objet à créer > string m_sClassName = "AudiRS4"; > // Chargement de l'assemblage > Assembly assembly = Assembly.LoadFrom(m_sClassName + ".dll"); > // Introspection des types > foreach(Type type in assembly.GetTypes()) { > if(m_sClassName == type.Name) { > // Un type correspond, création d'un objet > audi = Activator.CreateInstance(type); > } > } > //*** > > ainsi, ta variable "audi" pointe sur un objet de type AudiRS4 comme tu