Bon jour à tous,
peut-être que ce sera utile à certains...
C'est un petit compteur qui permet d'attribuer un numero à un objet. Si l'objet est supprimé, le numéro sera mis dans une pile qui sera trié, puis le plus petit sera réalloué ensuite.
Typiquement, je crée un singleton du compteur, j'appelle la méthode pour allouer le numéro dans le constructeur, et la méthode pour le désallouer quand je n'ai plus besoin de l'objet (Dans le dispose par exemple).
Si c'est inutile, je mettrai le poste en délestage...
La classe du compteur :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
 
using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;
 
namespace Counter
{
    /// <summary>
    /// Cette classe permet de créer un compteur d'instance d'un type d'objet particulier, qui gére la suppression et la redistribution des numéros d'instances.
    /// </summary>
    /// <typeparam name="T">Le type de l'objet</typeparam>
    public class InstanceCounter<T>
    {
 
        //L'arraylist contenant les numéros d'instances désalloués
        private ArrayList counterQueue = new ArrayList();
        //Dictionnaire contenant l'insatnce liée à son numéro d'instance
        private Dictionary<T, int> dictionary = new Dictionary<T, int>();
        private int counter = 0;
 
        /// <summary>
        /// Permet de faire commencer le compteur à la valeur souhaitée.
        /// </summary>
        public int SetCounter
        {
            set { counter = value; }
        }
 
        /// <summary>
        /// Constructeur
        /// </summary>
        public InstanceCounter()
        {
        }
 
        /// <summary>
        /// Permet de créer ou d'obtenir (si l'instance est déjà référencée) le numéro d'instance d'un objet.
        /// </summary>
        /// <param name="anObject">Un Objet du type déclaré</param>
        /// <returns>Le numéro d'instance</returns>
        public int CreateOrGetInstanceNumber(T anObject)
        {
            int instanceNumber;
            //L'objet est-il présent dans le dictionnaire? S'il l'est, on restitue son numéro.
            if (dictionary.ContainsKey(anObject))
            {
                dictionary.TryGetValue(anObject, out instanceNumber);
            }
            else
            {
                //La queue des numéros d'instances supprimés est-elle vide ou pleine? Si oui, on incrémente le compteur.
                if (counterQueue.Count == 0 || counterQueue.Count == counterQueue.Capacity)
                {
                    instanceNumber = ++counter;
                }
                // Sinon, on trie la queue afin de redistribuer le plus petit numéro d'instance.
                else
                {
                    counterQueue.Sort();
                    instanceNumber = (int)counterQueue[0];
                    //Onsupprime le plus petit élément de la queue.
                    counterQueue.RemoveAt(0);
                }
                //On référence l'objet et son numéro d'instance.
                dictionary.Add(anObject, instanceNumber);
            }
            //On retourne le numéro d'instance
            return instanceNumber;
        }
 
        /// <summary>
        /// Permet de désouscrire le numéro d'instance d'un objet, et de l'ajouter à la pile de redistribution.
        /// </summary>
        /// <param name="anObject">Un objet du type déclaré</param>
        public void DeleteInstanceNumber(T anObject)
        {
            int instanceNumber;
            //Si le dictionnaire contient l'objet
            if (dictionary.ContainsKey(anObject))
            {
                dictionary.TryGetValue(anObject, out instanceNumber);
                //On ajoute le numéro d'instance à la queue
                counterQueue.Add(instanceNumber);
                //On supprime la référence du dictionnaire
                dictionary.Remove(anObject);
            }
        }
 
        /// <summary>
        /// Permet de vider la queue des numéros d'instances devant-être réatribuée.
        /// </summary>
        public void ReInitializeInstanceQueue()
        {
            counterQueue.Clear();
        }
 
        /// <summary>
        /// Permet de connaître le nombre de numéros d'instances présent dans la queue de redistribution.
        /// </summary>
        /// <returns>Le nombre de numéros d'instances présents dans la queue </returns>
        public int GetNumberOfInstancesInQueue()
        {
            return counterQueue.Count;
        }
 
        /// <summary>
        /// Permet de fixer le nombre maximum de numéros d'instances d'objets à conserver.
        /// </summary>
        /// <param name="max">Le nombre de numéro d'instances à conserver.</param>
        public void SetMaximumInstanceQueue(int max)
        {
            //Le nombre de numéros d'instances en attente est-il inférieur à la valeur?
            if (GetNumberOfInstancesInQueue() > max)
            {
                throw new ArgumentOutOfRangeException();
            }
            //On modifie la capacité de la queue
            else
            {
                counterQueue.Capacity = max;
            }
        }
    }
}
La classe du singleton :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
using System;
using System.Text;
using System.Collections;
 
namespace Counter
{
    /// <summary>
    /// Assure l'unicité du compteur grâce à l'utilisation d'un singleton.
    /// </summary>
    /// <typeparam name="T">Le type du compteur.</typeparam>
    public class SingletonInstanceCounter<T>
    {
 
        private static InstanceCounter<T> singleton = null;
        private static readonly object padLock = new object();
 
        /// <summary>
        /// Constructeur privé du singleton.
        /// </summary>
        private SingletonInstanceCounter()
        {
        }
 
        /// <summary>
        /// Permet de créer ou d'accèder à l'instance unique du compteur.
        /// </summary>
        /// <returns>L'instance unique du compteur</returns>
        public static InstanceCounter<T> getInstance()
        {
            lock (padLock)
            {
                if (singleton == null)
                {
                    singleton = new InstanceCounter<T>();
                }
                return singleton;
            }
        }
    }
}