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

Signaler
Messages postés
100
Date d'inscription
samedi 26 octobre 2002
Statut
Membre
Dernière intervention
24 mai 2013
-
Messages postés
100
Date d'inscription
samedi 26 octobre 2002
Statut
Membre
Dernière intervention
24 mai 2013
-
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

7 réponses

Messages postés
441
Date d'inscription
mardi 2 décembre 2003
Statut
Membre
Dernière intervention
22 mai 2012
7
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 !??
Messages postés
441
Date d'inscription
mardi 2 décembre 2003
Statut
Membre
Dernière intervention
22 mai 2012
7
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 !
Messages postés
1540
Date d'inscription
lundi 26 mai 2003
Statut
Membre
Dernière intervention
1 août 2013
12
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.
Messages postés
441
Date d'inscription
mardi 2 décembre 2003
Statut
Membre
Dernière intervention
22 mai 2012
7
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 );
Messages postés
100
Date d'inscription
samedi 26 octobre 2002
Statut
Membre
Dernière intervention
24 mai 2013
1
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
Messages postés
100
Date d'inscription
samedi 26 octobre 2002
Statut
Membre
Dernière intervention
24 mai 2013
1
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).
Messages postés
100
Date d'inscription
samedi 26 octobre 2002
Statut
Membre
Dernière intervention
24 mai 2013
1
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