Bonjour,
il y a quelque chose que je ne comprends pas avec l'interface IEnumerable et/ou la méthode .Where().
Je cherche à pouvoir modifier la référence d'un élément de ma collection générique. Si j'utilise l'indexeur numérique, aucun problème. Si j'utilise l'indexeur qui passe par .Where() pour retrouver l'élément, ça ne fonctionne plus.
Voici mon code d'exemple :
La classe de mon élément de base:
Ma collection IEnumerable<Texte> qui pose problème :
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 class Texte { private string text = string.Empty; public string Text { get { return text; } set { text = value; } } public Texte(string newText) { text = newText; } }
Enfin, un programme Console pour l'exemple :
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 class TexteCollection : IEnumerable<Texte> { private List<Texte> liste = new List<Texte>(); /// <summary> /// Indexeur par index numérique: fonctionne (get et set) /// </summary> /// <param name="index"></param> /// <returns></returns> public Texte this[int index] { get { return liste[index]; } set { liste[index] = value; } } /// <summary> /// Indexeur par condition : le set ne fonctionne pas. /// </summary> /// <param name="text"></param> /// <returns></returns> public Texte this[string text] { get { IEnumerable<Texte> list = liste.Where(t => t.Text == text); if ( list.Count() > 0 ) return list.ElementAt(0); else return null; } set { IEnumerable<Texte> list = liste.Where(t => t.Text == text); if ( list.Count() == 1 ) { Texte t = list.ElementAt(0); //t.Text = value.Text; t = value; } } } public void Add(string text) { liste.Add(new Texte(text)); } private IEnumerator<Texte> Enumerator() { for ( int i = 0; i < liste.Count; i++ ) { yield return liste[i]; } } #region IEnumerable<Texte> Membres public IEnumerator<Texte> GetEnumerator() { return Enumerator(); } #endregion #region IEnumerable Membres System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { return Enumerator(); } #endregion }
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 class Program { static void Main(string[] args) { TexteCollection collection = new TexteCollection(); collection.Add("test1"); // index 0 collection.Add("test2"); // index 1 Console.WriteLine("[0]=" + collection[0].Text); Console.WriteLine("[1]=" + collection[1].Text); collection["test1"] = new Texte("test 1 remplacé"); Console.WriteLine("[0]=" + collection[0].Text); Console.ReadKey(); } }
Tel qu'implémenté, la console affiche :
Alors que la dernière ligne devrait être "[0]=test 1 remplacé".
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 [0]=test1 [1]=test2 [0]=test1
Si je modifie le set de mon indexeur dans TexteCollection de cette façon:
Ca fonctionne, j'ai la sortie console:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 set { IEnumerable<Texte> list = liste.Where(t => t.Text == text); if ( list.Count() == 1 ) { Texte t = list.ElementAt(0); t.Text = value.Text; // t = value; } }
J'ai l'impression d'avoir oublié quelque chose d'une importance primordiale... mais je ne comprends pas pourquoi cette différence entre
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 [0]=test1 [1]=test2 [0]=test1 remplacé
et
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2t.Text = value.Text;
Sachant bien évidemment que ce qui m'intéresse est de remplacer mon objet (donc par référence).
Code : Sélectionner tout - Visualiser dans une fenêtre à part t = value;
Merci d'avance pour ceux qui m'ont lu, et pour toute aide...
Bonne journée
Partager