Liste d'objet générique avec type variable [Résolu]

cs_vincnet68 100 Messages postés samedi 26 octobre 2002Date d'inscription 24 mai 2013 Dernière intervention - 3 mai 2011 à 10:54 - Dernière réponse : cs_vincnet68 100 Messages postés samedi 26 octobre 2002Date d'inscription 24 mai 2013 Dernière intervention
- 3 mai 2011 à 15:17
Bonjour,

J'ai créé une classe avec type générique <T>
Le type est donnée par le type d'un autre objet :

Première question comment peut-on donner le type de la classe lors de l'execution et pas lors de la compilation (maClasse<source.Type>) ?

Seconde question, peut-on faire une liste de ces objets avec des objets de type différent (objet 1 : string, objet 2 : int, ...) ?

J'espère avoir été clair dans mon explication

Merci de votre aide.

Vincnet68
Afficher la suite 

7 réponses

Répondre au sujet
LUDINSKI 441 Messages postés mardi 2 décembre 2003Date d'inscription 22 mai 2012 Dernière intervention - 3 mai 2011 à 13:03
+3
Utile
Tu peux passer par une interface dans le genre :
public interface IMaClasse
{
}


Donc ta classe générique serait déclaré comme cela :
public class MaClasse<T> : IMaClasse
{
}


Et du coup tu peux écrire :
List list = new List();

list.Add(new MaClasse());
list.Add(new MaClasse<String>());


Mais je ne vois pas l’intérêt de faire cela...
Qu'elle est la finalité de ta demande !??
Cette réponse vous a-t-elle aidé ?  
Commenter la réponse de LUDINSKI
LUDINSKI 441 Messages postés mardi 2 décembre 2003Date d'inscription 22 mai 2012 Dernière intervention - 3 mai 2011 à 14:57
+3
Utile
Si, ma solution plus haut fonctionne... mais je te donnai juste un exemple avec List<> !! Voici le même exemple pour ton code (en simplifié) :

public interface IMaClasse
{
    object Value { get; }
}

public class MaClasse<T> : IMaClasse
{
    private T _value;

    public MaClasse( T value )
    {
        _value = value;
    }

    public object Value
    {
        get { return _value; }
    }
}


Et pour ta liste :
private void AddMaClasse( ref List mesClasses, object value )
{
    Type[] valueType = new Type[] { value.GetType() };
    Type maClasseType = typeof( MaClasse<> ).MakeGenericType( valueType );
    mesClasses.Add( (IMaClasse)maClasseType.GetConstructor( valueType ).Invoke( new object[]{ value } ) );
}


A utilisé de cette manière :
List mesClasses = new List();
AddMaClasse( ref mesClasses, 123 );
AddMaClasse( ref mesClasses, "Toto" );
AddMaClasse( ref mesClasses, 124.8D );
AddMaClasse( ref mesClasses, 124.8f );


Ca devrait t'aider... si j'ai bien compris ta requête !
Cette réponse vous a-t-elle aidé ?  
Commenter la réponse de LUDINSKI
cs_jopop 1540 Messages postés lundi 26 mai 2003Date d'inscription 1 août 2013 Dernière intervention - 3 mai 2011 à 11:06
0
Utile
Salut,

alors j'utilise pas trop les templates (d'ailleurs ça doit même plus s'appeler comac en C# ^^). Mais en gros quand tu définis une classe du genre :
public class maClass<T> { .. }

tu instancies alors un objet du genre :
maClass<string> mc = new maClass<string>();


Le fonctionnement en C++ était, lors de la compilation : le compilo regarde quelles spécifications de template tu as et il implémente implicitement autant de classes que d'usages différents du template. Donc c'est au moment de la compilation, pas de l'execution. Je pense que pour C# c'est toujours pareil.

Tu peux faire des listes exactement comme tu le souhaites, sachant que tout type dérive du type object, il suffit donc d'utiliser maClass<object> pour y coller ce que tu veux.

Je ne sais pas quel est le but final de ton code, mais peut-être que ce que tu recherches existe déjà via les ArrayList et autre Collections fournies par le framework.
Commenter la réponse de cs_jopop
LUDINSKI 441 Messages postés mardi 2 décembre 2003Date d'inscription 22 mai 2012 Dernière intervention - 3 mai 2011 à 11:51
0
Utile
Salut,

Pour donner le type en cours d'exécution, tu dois passer par la réflexion.
Voici un exemple pour instancier un objet de type List<Double> :

Type doubleType = typeof( Double );
Type doubleList = typeof( List<> ).MakeGenericType( new Type[]{ doubleType } );

// Instancie un objet de type List<Double>
IList doubleListInstance = (IList)doubleList.GetConstructor( new Type[ 0 ] ).Invoke( null );
Commenter la réponse de LUDINSKI
cs_vincnet68 100 Messages postés samedi 26 octobre 2002Date d'inscription 24 mai 2013 Dernière intervention - 3 mai 2011 à 12:48
0
Utile
J'explique un peu mieux ma demande :

Je créé une classe : maClasse<T>
Je souhaite maintenant créer une liste de "maClasse".

Ca donnerai quelque chose comme ceci :

List<maClasse> list = new List<maClasse>();

list.Add(new maClasse<typeof(objet1)>());
list.Add(new maClasse<typeof(objet2)>());


Mais ceci ne fonctionne pas car je doit donner le type de la liste. Est-ce que quelqu'un à une idée ?

Merci de votre aide.

Vincnet68
Commenter la réponse de cs_vincnet68
cs_vincnet68 100 Messages postés samedi 26 octobre 2002Date d'inscription 24 mai 2013 Dernière intervention - 3 mai 2011 à 13:24
0
Utile
Merci pour ton aide, cela fonctionne.

Maintenant j'ai le deuxième problème :

new maClasse<typeof(objet1)>();


La solution de LUDINSKI ne fonctionne pas.

Comment puis-je passer le parametre <T> en tant que variable (type d'une autre variable ?

Merci

PS : pour la finalité, c'est un peu compliqué disons, pour faire simple, que je fait une sorte d'héritage (l'objet voulu n'est pas héritable).
Commenter la réponse de cs_vincnet68
cs_vincnet68 100 Messages postés samedi 26 octobre 2002Date d'inscription 24 mai 2013 Dernière intervention - 3 mai 2011 à 15:17
0
Utile
Merci ta solution fonctionne,

Mais cela me génère beaucoup trop de soucis et modifs que je n'avais pas envisagés (timing à respecter et c'est la première fois que je travaille avec du générique).
Je vais laisser tomber cette altérnative et travailler avec des try et du cast.

Merci à tous de votre aide

Vincnet68
Commenter la réponse de cs_vincnet68

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.