Générique et processus

Résolu
moi411 Messages postés 179 Date d'inscription samedi 22 novembre 2003 Statut Membre Dernière intervention 25 juin 2017 - 27 mai 2011 à 23:25
moi411 Messages postés 179 Date d'inscription samedi 22 novembre 2003 Statut Membre Dernière intervention 25 juin 2017 - 31 mai 2011 à 21:55
Bonsoir,
J'ai une classe qui doit trier des listes de n'importe quel type (int, string ... et donc Process).

J'ai définis une classe générique comme ça:

public class TriGen<T> where T : IComparable<T>
{
//propriétés, ici: Liste
//constructeurs
//méthodes de tris (shell, bulles...), ici: TriageList()
}

puis je crée mes listes qui utiliseront mes méthodes de tris et évidemment affichage du résultat. Comme ça:

List<DateTime> listeDate = new List<DateTime>();
listeDate.add(00/00/0000); ...

TriGen<DateTime> triage = new TriGen<DateTime>(listeDate);
triage.TriShell();
foreach (DateTime d in triage.Liste)
{
listBox1.Items.Add(d.ToLongDateString());
}

Comme ça, ça fonctionne très bien mais si je veux trier des processus, j'utilise un paramètre de type, Process, et j'obtiens alors l'erreur suivante:

The type 'System.Diagnostics.Process' cannot be used as type parameter 'T'...

Voilà, si quelqu'un peut m'aider à résoudre cette erreur!
A bientôt.
moi

9 réponses

cs_coq Messages postés 6349 Date d'inscription samedi 1 juin 2002 Statut Membre Dernière intervention 2 août 2014 101
31 mai 2011 à 20:12
Salut,

PerNameProcessComparer test = new PerNameProcessComparer(listeProc);
bonne compilation mais erreur (impossible de comparer 2 éléments).

Je ne vois pas comment ça pourrait compiler avec l'exemple de code que j'ai donné.

TriGen test = TriGen(listeProc);
Erreur avant même la compilation (Process est un type utilisé comme une variable.

Là je ne vois pas pourquoi ça ne compilerais pas avec l'exemple de code que j'ai donné.


En reprennant le code que j'ai donné juste avant, basé sur ta structure d'origine, ça donne ce genre de chose :

Process, tri par nom :
Process[] processes = Process.GetProcesses();
TriGen processesTriGen = new TriGen(processes);

// Tri par nom
processesTriGen.Sort(new PerNameProcessComparer());
foreach (Process p in processesTriGen.Tableau) { Console.WriteLine("{0} (PID {1})", p.ProcessName, p.Id); }


Process, tri par PID :
Process[] processes = Process.GetProcesses();
TriGen processesTriGen = new TriGen(processes);

// tri par PID
processesTriGen.Sort(new PerPIDProcessComparer());
foreach (Process p in processesTriGen.Tableau) { Console.WriteLine("{0} (PID {1})", p.ProcessName, p.Id); }


Char, tri par défaut :
TriGen<char> characters = new TriGen<char>(new char[] { 'd', 'a', 'c', 'b' });

// Tri par défaut
characters.Sort();
foreach (char s in characters.Tableau) { Console.WriteLine(s); }



/*
coq
CoqBlog
*/
3
cs_coq Messages postés 6349 Date d'inscription samedi 1 juin 2002 Statut Membre Dernière intervention 2 août 2014 101
29 mai 2011 à 11:36
Oula, je dois avouer avoir en fin de compte un peu de mal à saisir ce que tu veux faire vu que tu as maintenant 2 façons de trier au lieu d'une.

Ce que je proposais dans mon précédent message était plutôt pour la première solution (rapidement : gestion d'erreur etc à ajouter) :
    public class TriGen<T>
    {
        public T[] Tableau { get; set; }
        public IComparer<T> DefaultComparer { get { return Comparer<T>.Default; } }

        public TriGen(T[] liste)
        {
            Tableau = liste;
            // ...
        }

        // ...

        public void Sort()
        {
            this.Sort(this.DefaultComparer);
        }

        public void Sort(IComparer<T> comparer)
        {
            Array.Sort(Tableau, comparer);
        }
    }

    public class PerNameProcessComparer : Comparer
    {
        private StringComparer comparer = StringComparer.OrdinalIgnoreCase;

        public override Int32 Compare(Process x, Process y)
        {
            if (Object.ReferenceEquals(x, y)) return 0;
            if (x == null) return -1;
            if (y == null) return 1;

            return this.comparer.Compare(x.ProcessName, y.ProcessName);
        }
    }

    public class PerPIDProcessComparer : Comparer
    {
        public override Int32 Compare(Process x, Process y)
        {
            if (Object.ReferenceEquals(x, y)) return 0;
            if (x == null) return -1;
            if (y == null) return 1;

            return x.Id.CompareTo(y.Id);
        }
    }


Celà permet notamment une plus grande souplesse, côté code utilisateur, pour le choix de la façon de trier.


/*
coq
CoqBlog
*/
2
cs_coq Messages postés 6349 Date d'inscription samedi 1 juin 2002 Statut Membre Dernière intervention 2 août 2014 101
28 mai 2011 à 10:00
Bonjour,

"where T : IComparable<T>"
Process n'implémente pas cette interface (la suite du message d'erreur doit le dire il me semble).


/*
coq
CoqBlog
*/
0
moi411 Messages postés 179 Date d'inscription samedi 22 novembre 2003 Statut Membre Dernière intervention 25 juin 2017 3
28 mai 2011 à 11:03
Salut,
Oui c'est exacte, la suite me dit tout ça... Mais dans ce cas est-ce qu'il existe un moyen de trier mes processus, dans ma classe?

Sinon je les convertit en string (Process.ProcessName) mais ça m'oblige à écrire une boucle de plus...

Dans mon idée ma classe générique devait servir à empêcher de devoir convertir en string (ou en autre chose) tout et n'importe quoi!

En tout cas merci d'avoir répondu.
A la prochaine.
moi
0

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

Posez votre question
cs_coq Messages postés 6349 Date d'inscription samedi 1 juin 2002 Statut Membre Dernière intervention 2 août 2014 101
28 mai 2011 à 11:16
Salut,

Il peut y avoir plusieurs solutions dont :
- écrire une autre version de la classe TriGen sans la contrainte mais qui demande la spécification d'une instance d'une implémentation de IComparer<T> qui sera utilisée dans les codes de tri. Exemple de cas similaires : SortedDictionary<TKey, TValue>(IComparer<TKey>), List<T>.Sort(IComparer<T>)
- avec la classe TriGen existante : écrire une classe implémentant IComparable<T> pour encapsuler l'instance de Process dans les scénarios de tri


/*
coq
CoqBlog
*/
0
moi411 Messages postés 179 Date d'inscription samedi 22 novembre 2003 Statut Membre Dernière intervention 25 juin 2017 3
28 mai 2011 à 15:27
Salut,
Je pense avoir compris le système mais une fois la classe créée comme ça:

public class TriGen<System.Diagnostics.Process> : IComparable<System.Diagnostics.Process>
{
}

Je dois implémenter, l'interface IComparable<System.Diagnostics.Process> qui dois ressembler à ça:

int IComparable.CompareTo(Process other)
{
//je ne comprends pas comment faire!!!
}

Si tu pouvais me donner encore une piste!!!
Je te remercie d'avance.
moi
0
moi411 Messages postés 179 Date d'inscription samedi 22 novembre 2003 Statut Membre Dernière intervention 25 juin 2017 3
29 mai 2011 à 10:03
Salut,
Je pense avoir trouvé finalement.

1) La classe générique (pour trier n'importe quel type de tableau ou list):

public class TriGen<T>
{
public T[] Tableau { get; set; }
public TriGen(T[] liste)
{
Tableau = liste;
TriShell();
//TriBulles();
//Array.Sort(Tableau);
}


public List<T> Liste { get; set; } //Liste
public TriGen(ListBox liste) //Constructeur pour une listBox
{
Liste = new List<T>();
foreach (T item in liste.Items) { Liste.Add(item); }
TriShell();
//TriBulles();
//Liste.Sort();
}
public TriGen(List<T> liste) //Constructeur pour list
{
Liste = liste;
TriShell();
//TriBulles();
//Liste.Sort();
}
}




2) La classe pour trier les processus:

public class TriGen : IComparable<TriGen>
{
public Process Proc { get; set; }
public TriGen(Process p)
{
Proc = p;
}


//Surcharge toString() pour afficher les processus par leur nom;

public override string ToString()
{
return Proc.ProcessName;
}


//implémentation Interface

int IComparable<TriGen>.CompareTo(TriGen other)
{
string otherProc = other.Proc.ProcessName;
return this.Proc.ProcessName.CompareTo(otherProc);
}
}


3) Utilisation

//processus
Process[] allProc = Process.GetProcesses();
List<TriGen> procList = new List<TriGen>();
foreach (Process proc in allProc) { procList.Add(new TriGen(proc)); }
procList.Sort();
foreach (TriGen p in procList) { listBox1.Items.Add(p); }

//char
TriGen<char> triage7 = new TriGen<char>(liste7);
foreach (char s in triage7.Tableau) { listBox1.Items.Add(s); }

//string
listBox1.Items.Add("< --- > ListBox de string");
TriGen<string> triage4 = new TriGen<string>(listBox2);
foreach (string s in triage4.Liste) { listBox1.Items.Add(s); }


Voila c'est à peu près tout...
moi
0
moi411 Messages postés 179 Date d'inscription samedi 22 novembre 2003 Statut Membre Dernière intervention 25 juin 2017 3
31 mai 2011 à 18:11
Salut,
Je ne comprends pas bien le principe...
Je comprends le code mais pas le fonctionnement!
Comment je trie mes processus? Je dois créer quoi comme objet?

Si je fais (listeProc est un tableau):

PerNameProcessComparer test = new PerNameProcessComparer(listeProc);

bonne compilation mais erreur (impossible de comparer 2 éléments).

et si je fais (listeProc est un tableau):

TriGen test = TriGen(listeProc);

Erreur avant même la compilation (Process est un type utilisé comme une variable.

Je sèche!!!

Je vais encore te demander un coup de main!
Merci d'avance.
moi
0
moi411 Messages postés 179 Date d'inscription samedi 22 novembre 2003 Statut Membre Dernière intervention 25 juin 2017 3
31 mai 2011 à 21:55
Re,
Bon et bien ça marche...
J'ai dû faire une erreur (même surement) mais je ne l'ai pas vue!
En retapant le tout, ça a fonctionné (je ne fais pas de copier/coller).
En attendant ça fonctionne correctement.

Merci pour tout et à bientôt!
moi
0
Rejoignez-nous