Bonjour tout le monde,

Je joue actuellement avec des List<T> d'objets afin de comparer des informations que j'ai en memoire avec d'autres plus fraiches recuperee depuis le systeme. Tout semble bien lorsque que le systeme me donne de nouvelles entrees (en plus ou en moins), mais des lors que je passe par un WebService pour ajouter "manuellement" une information, tout se gate.

Explication du fonctionnement:
- Un Timer recupere toutes les X minutes des informations du systeme (en l'occurrence du serveur DHCP, mais c'est un detail).
- Un WebService tourne et accepte des requetes pour creer de nouvelles donnees dans le DHCP
- Mon Main(), qui orchestre le tout et declare en statique une classe qui contient les differentes listes d'objets.

Cas d'utilisation:
  • Le service demarre, lance un new Host() pour le WebService, instancie une classe "Inventaire" qui recupere les informations (la fameuse classe statique commune a tout le programme), puis un Timer (celui qui recupere des donnees fraiches).
  • On peut utiliser le WS pour ajouter des infos. Dans ce cas, le code ajoute dans le serveur DHCP ce qu'on lui passe, et ajoute ensuite l'objet dans les listes internes (classe statique Inventaire) pour eviter lors d'un rafraichissement des donnees une "difference" entre la memoire et le DHCP.


Probleme :
Je rencontre la fameuse Null Reference Exception dans le dernier cas: la mise a jour via WebServices. Tout se passe correctement (ajout dans le systeme, ajout de l'objet a la liste interne) jusqu'au moment ou un rafraichissement a lieu.
J'ai donc la liste d'objets List<DHCPAddress> interne, et la meme recuperee du systeme. Pour savoir si des objets ont ete ajoutes/supprimes dans l'une ou l'autre, je fais ceci:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
 
addressesCnt = this.AddressesList.Except<DHCPAddress>(cmp.AddressesList).Count<DHCPAddress>(); // Marche impecc'
 
IEnumerable<DHCPAddress> diffList = cmp.AddressesList.Except<DHCPAddress>(this.AddressesList);
if (diffList == null) log.writeEventLog(EventLogEntryType.Error, "diffList is Null");
else log.writeEventLog(EventLogEntryType.Error, "Not Null");
Int32 diffCnt = diffList.Count(); // NRE catchee
J'ai lance le debugger, et j'ai trouve lors de l'appel a la premiere ligne que le NRE existe directement sans utilisation du Except (ce qui m'etonne car j'avais cru comprendre qu'il y avait une execution differee) dans la variable diffList.
De meme, en faisant un foreach sur cmp.AddressesList et this.AddressesList, je constate que j'ai bel et bien le meme nombre de donnees, avec le meme contenu...

Afin de pouvoir utiliser Except, j'ai implemente les deux methodes Equals sur ma classe DHCPAddress que voici:
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
 
    [DataContract]
    public class DHCPAddress : DHCPObject, IEquatable<DHCPAddress>
    {
        public enum AddressStatus { Static, Assigned, Released };
 
        private Boolean _isLease = false;
        private String _scopeAddr = "";
        private String _address = "";
        private String _MACAddress = "";
        private String _name = "";
        private Int32 _startTime = 0;
        private Int32 _validity = 0;
        private AddressStatus _status = AddressStatus.Static;
        private long _counter = 0;
 
        // debug
        Logs log = Logs.Instance;
        // end debug
 
        public DHCPAddress(String ScopeAddress, Boolean Lease = false, long Counter = 0, AddressStatus Status = AddressStatus.Assigned)
        {
            this.ScopeAddr = ScopeAddress;
            this._isLease = Lease;
            if (!Lease)
                this._status = AddressStatus.Static;
            else
            {
                this._status = Status;
                this._counter = Counter;
            }
        }
 
        #region IEquatable
        public override bool Equals(object obj)
        {
            if (obj == null)
                return base.Equals(obj);
            if (!(obj is DHCPAddress)) throw new InvalidCastException("Expected type: DHCPAddress");
            return this.Equals(obj as DHCPAddress);
        }
 
        public Boolean Equals(DHCPAddress cmp)
        {
            if (_address == null) log.writeEventLog(System.Diagnostics.EventLogEntryType.Error, "CMP null 1"); else log.writeEventLog(System.Diagnostics.EventLogEntryType.Error, "CMP notnull 1");
            if (_counter == null) log.writeEventLog(System.Diagnostics.EventLogEntryType.Error, "CMP null 2"); else log.writeEventLog(System.Diagnostics.EventLogEntryType.Error, "CMP notnull 2");
            if (IsLease == null) log.writeEventLog(System.Diagnostics.EventLogEntryType.Error, "CMP null 3"); else log.writeEventLog(System.Diagnostics.EventLogEntryType.Error, "CMP notnull 3");
            if (_MACAddress == null) log.writeEventLog(System.Diagnostics.EventLogEntryType.Error, "CMP null 4"); else log.writeEventLog(System.Diagnostics.EventLogEntryType.Error, "CMP notnull 4");
            if (_name == null) log.writeEventLog(System.Diagnostics.EventLogEntryType.Error, "CMP null 5"); else log.writeEventLog(System.Diagnostics.EventLogEntryType.Error, "CMP notnull 5");
            if (_scopeAddr == null) log.writeEventLog(System.Diagnostics.EventLogEntryType.Error, "CMP null 6"); else log.writeEventLog(System.Diagnostics.EventLogEntryType.Error, "CMP notnull 6");
            if (_startTime == null) log.writeEventLog(System.Diagnostics.EventLogEntryType.Error, "CMP null 7"); else log.writeEventLog(System.Diagnostics.EventLogEntryType.Error, "CMP notnull 7");
            if (_status == null) log.writeEventLog(System.Diagnostics.EventLogEntryType.Error, "CMP null 8"); else log.writeEventLog(System.Diagnostics.EventLogEntryType.Error, "CMP notnull 8");
            if (_validity == null) log.writeEventLog(System.Diagnostics.EventLogEntryType.Error, "CMP null 9"); else log.writeEventLog(System.Diagnostics.EventLogEntryType.Error, "CMP notnull 9");
            // http://msdn.microsoft.com/fr-fr/library/bsc2ak47.aspx
            if (cmp == null) { return false; }
            if (Object.ReferenceEquals(this, cmp)) { log.writeEventLog(System.Diagnostics.EventLogEntryType.Warning, "3"); return true; }
            else if (IsLease == cmp.IsLease &&
                Address == cmp.Address &&
                MACAddress == cmp.MACAddress &&
                Name == cmp.Name &&
                ScopeAddr == cmp.ScopeAddr)
            {
                return true;
            }
            log.writeEventLog(System.Diagnostics.EventLogEntryType.Warning, "5");
            //log.writeEventLog(System.Diagnostics.EventLogEntryType.Error, String.Format("THIS -- Lease: {0} // add: {1} // mac: {2} // name: {3} // scope: {4}",
            //    IsLease, Address, MACAddress, Name, ScopeAddr));
            return false;
        }
 
        public override int GetHashCode()
        {
            return _isLease.GetHashCode() | _MACAddress.GetHashCode() & _name.GetHashCode();
        }
        #endregion IEquatable
 
        #region Properties
        [DataMember]
        public Boolean IsLease { get { return this._isLease; }
                                 set { this._isLease = value; } }
        [DataMember]
        public String Address { get { return this._address.ToString(); }
                                set { this._address = value; } }
        [DataMember]
        public String MACAddress { get { return this._MACAddress.Replace("-", "").Replace(":", ""); }
                                   set { this._MACAddress = value.Replace("-", "").Replace(":", ""); } }
        [DataMember]
        public String Name { get { return this._name; }
                             set { this._name = value; } }
        [DataMember]
        public String StartTime { get { return this._startTime.ToString(); }
                                  set { this._startTime = Int32.Parse(value); } }
        [DataMember]
        public String Validity { get { return this._validity.ToString(); }
                                 set { this._validity = Int32.Parse(value); } }
        [DataMember]
        public AddressStatus Status { get { return this._status; }
                                      set { this._status = value; } }
        [DataMember]
        public String ScopeAddr { get { return this._scopeAddr; }
                                  set { this._scopeAddr = value; } }
        [DataMember]
        public long Counter { get { return this._counter; }
                              set { this._counter = value; } }
        #endregion Properties
 
        public override String ToString()
        {
            return String.Format(@"dhcp server 127.0.0.1 scope {0} add reservedip {1} {2} {3} """" BOTH", ScopeAddr, Address, MACAddress, Name);
        }
    }
A aucun moment je n'ai de Null sur les membres de la classe DHCPAddress (le message de la NRE dis que l'exception a ete levee dans Equals pourtant...).

Exception trapee:
[DHCPInventory] Could not compare dump to loaded configuration.
Exception: La référence d'objet n'est pas définie à une instance d'un objet.
à Projet.DHCPAddress.Equals(DHCPAddress cmp)
à System.Collections.Generic.GenericEqualityComparer`1.Equals(T x, T y)
à System.Linq.Set`1.Find(TElement value, Boolean add)
à System.Linq.Enumerable.<ExceptIterator>d__99`1.MoveNext()
à System.Linq.Enumerable.Count[TSource](IEnumerable`1 source)
à Projet.DHCPInventory._updateIfNewer(DHCPInventory cmp)
à Projet.DHCPInventory.Update(DHCPInventory cmp)
Quelqu'un aurait-il une idee ? Surtout que ca ne plante QUE lors de l'utilisation des WebServices (un ajout ou une suppression en local est correctement gere)...

Merci d'avance et desole pour la tartine