Générique et processus [Résolu]

moi411 180 Messages postés samedi 22 novembre 2003Date d'inscription 25 juin 2017 Dernière intervention - 27 mai 2011 à 23:25 - Dernière réponse : moi411 180 Messages postés samedi 22 novembre 2003Date d'inscription 25 juin 2017 Dernière intervention
- 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
Afficher la suite 

Votre réponse

9 réponses

Meilleure réponse
cs_coq 6366 Messages postés samedi 1 juin 2002Date d'inscription 2 août 2014 Dernière intervention - 31 mai 2011 à 20:12
3
Merci
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
*/

Merci cs_coq 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 100 internautes ce mois-ci

Commenter la réponse de cs_coq
cs_coq 6366 Messages postés samedi 1 juin 2002Date d'inscription 2 août 2014 Dernière intervention - 29 mai 2011 à 11:36
2
Merci
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
*/
Commenter la réponse de cs_coq
cs_coq 6366 Messages postés samedi 1 juin 2002Date d'inscription 2 août 2014 Dernière intervention - 28 mai 2011 à 10:00
0
Merci
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
*/
Commenter la réponse de cs_coq
moi411 180 Messages postés samedi 22 novembre 2003Date d'inscription 25 juin 2017 Dernière intervention - 28 mai 2011 à 11:03
0
Merci
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
Commenter la réponse de moi411
cs_coq 6366 Messages postés samedi 1 juin 2002Date d'inscription 2 août 2014 Dernière intervention - 28 mai 2011 à 11:16
0
Merci
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
*/
Commenter la réponse de cs_coq
moi411 180 Messages postés samedi 22 novembre 2003Date d'inscription 25 juin 2017 Dernière intervention - 28 mai 2011 à 15:27
0
Merci
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
Commenter la réponse de moi411
moi411 180 Messages postés samedi 22 novembre 2003Date d'inscription 25 juin 2017 Dernière intervention - 29 mai 2011 à 10:03
0
Merci
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
Commenter la réponse de moi411
moi411 180 Messages postés samedi 22 novembre 2003Date d'inscription 25 juin 2017 Dernière intervention - 31 mai 2011 à 18:11
0
Merci
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
Commenter la réponse de moi411
moi411 180 Messages postés samedi 22 novembre 2003Date d'inscription 25 juin 2017 Dernière intervention - 31 mai 2011 à 21:55
0
Merci
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
Commenter la réponse de moi411

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.