Liste d'objet générique avec type variable

Résolu
cs_vincnet68 Messages postés 100 Date d'inscription samedi 26 octobre 2002 Statut Membre Dernière intervention 24 mai 2013 - 3 mai 2011 à 10:54
cs_vincnet68 Messages postés 100 Date d'inscription samedi 26 octobre 2002 Statut Membre Dernière intervention 24 mai 2013 - 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

7 réponses

LUDINSKI Messages postés 441 Date d'inscription mardi 2 décembre 2003 Statut Membre Dernière intervention 22 mai 2012 8
3 mai 2011 à 13:03
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 !??
3
LUDINSKI Messages postés 441 Date d'inscription mardi 2 décembre 2003 Statut Membre Dernière intervention 22 mai 2012 8
3 mai 2011 à 14:57
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 !
3
cs_jopop Messages postés 1540 Date d'inscription lundi 26 mai 2003 Statut Membre Dernière intervention 1 août 2013 12
3 mai 2011 à 11:06
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.
0
LUDINSKI Messages postés 441 Date d'inscription mardi 2 décembre 2003 Statut Membre Dernière intervention 22 mai 2012 8
3 mai 2011 à 11:51
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 );
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
cs_vincnet68 Messages postés 100 Date d'inscription samedi 26 octobre 2002 Statut Membre Dernière intervention 24 mai 2013 1
3 mai 2011 à 12:48
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
0
cs_vincnet68 Messages postés 100 Date d'inscription samedi 26 octobre 2002 Statut Membre Dernière intervention 24 mai 2013 1
3 mai 2011 à 13:24
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).
0
cs_vincnet68 Messages postés 100 Date d'inscription samedi 26 octobre 2002 Statut Membre Dernière intervention 24 mai 2013 1
3 mai 2011 à 15:17
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
0
Rejoignez-nous