IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C# Discussion :

NRE sur un Except comparant deux Lists<Obj>


Sujet :

C#

  1. #1
    Invité
    Invité(e)
    Par défaut NRE sur un Except comparant deux Lists<Obj>
    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

  2. #2
    Membre émérite Avatar de Guulh
    Homme Profil pro
    Inscrit en
    Septembre 2007
    Messages
    2 160
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2007
    Messages : 2 160
    Points : 2 925
    Points
    2 925
    Par défaut
    Hello,

    ca serait pas "log" qui serait null, par hasard ?

    Aussi, fais-gaffe à MacAddress : tu fais des "Replace", ce qui peut lever une NRE si "value" ou "_MacAddress" est null.

    Sinon, tu as essayé de metter un point d'arrêt dans Equals pour voir à quelle ligne l'exeception se produit ?

    Pour l'exécution différée, d'ailleurs : elle l'est, sauf si tu appelles une méthode qui nécessite le parcours, comme Count() par exemple.

  3. #3
    Invité
    Invité(e)
    Par défaut
    Alors la... tout d'abord merci, c'etait en effet log qui etait null (mais franchement je ne comprends pas comment c'est possible...).
    J'avais bien mis un breakpoint mais tout semblait correct, et j'avais bien des debugs d'affiches dans mon event log Du coup je n'ai rien soupconne...

    Pour le coup de MacAddress, si _MacAddress est initialise a "" ca ne devrait normalement rien produire il me semble non ? Par contre pour le setter, il n'y a pas un controle de fait la dessus ? Sinon je peux le rajouter effectivement !

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Comparer deux listes
    Par timtim2007 dans le forum Prolog
    Réponses: 7
    Dernier message: 07/06/2019, 09h02
  2. operator== pour comparer deux listes
    Par docky dans le forum C++
    Réponses: 10
    Dernier message: 18/05/2008, 17h49
  3. Requete pour comparer deux listes
    Par Jean-Christoph dans le forum Langage SQL
    Réponses: 3
    Dernier message: 17/04/2008, 13h29
  4. Comparer deux listes de listes
    Par julien80 dans le forum Prolog
    Réponses: 5
    Dernier message: 05/03/2008, 18h18
  5. [C# 2.0] Comparer deux listes
    Par Rodie dans le forum Windows Forms
    Réponses: 4
    Dernier message: 01/08/2006, 00h40

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo