2
votes

Comment puis-je vérifier si un objet (que je dois insérer dans une liste) est déjà dans la liste en utilisant C #?

Je ne suis pas tellement dans C # et .NET . J'ai le problème suivant.

Dans mon code, j'ai quelque chose comme ceci:

public class UOR
{
    private string unitaOperativaResponsabile;

    public string UnitaOperativaResponsabile
    {
        get { return unitaOperativaResponsabile; }
        set { unitaOperativaResponsabile = value; }
    }
    private string areaOrganizzativaOmogenea;

    public string AreaOrganizzativaOmogenea
    {
        get { return areaOrganizzativaOmogenea; }
        set { areaOrganizzativaOmogenea = value; }
    }
    private string siglaAOO;

    public string SiglaAOO
    {
        get { return siglaAOO; }
        set { siglaAOO = value; }
    }
    private string siglaUOR;

    public string SiglaUOR
    {
        get { return siglaUOR; }
        set { siglaUOR = value; }
    }
    private int idUor;

    public int IdUor
    {
        get { return idUor; }
        set { idUor = value; }
    }

    private bool attiva;

    public bool Attiva
    {
        get
        {
            return attiva;
        }

        set
        {
            attiva = value;
        }
    }

    private int alias;

    public int Alias
    {
        get
        {
            return alias;
        }

        set
        {
            alias = value;
        }
    }

    public override int GetHashCode()
    {

        // Get the hash code for the Textual field if it is not null.
        int hashTextual = siglaAOO == null ? 0 : siglaAOO.GetHashCode();

        // Get the hash code for the Digital field.
        int hashDigital = idUor.GetHashCode();

        // Calculate the hash code for the object.
        return hashDigital ^ hashTextual;
    }

    public override bool Equals(System.Object obj)
    {
        // If parameter is null return false.
        if (obj == null)
        {
            return false;
        }

        // If parameter cannot be cast to Point return false.
        UOR p = obj as UOR;
        if ((System.Object)p == null)
        {
            return false;
        }

        // Return true if the fields match:
        return (idUor == p.idUor) && (siglaAOO.Equals(p.siglaAOO));
    }

    public bool Equals(UOR p)
    {
        // If parameter is null return false:
        if ((object)p == null)
        {
            return false;
        }

        // Return true if the fields match:
        return (idUor == p.idUor) && (siglaAOO.Equals(p.siglaAOO));
    }
}

visibUtils.Uors est une liste de Objet UOR .

Comme vous pouvez le voir, je suis en train d'itérer sur une liste d'identifiants ( visibilitaPostRidistribuzioni ). Pour chaque ID, je récupère un objet UOR uor et je l'ajoute à la liste visibUtils.Uors .

Ce dont j'ai besoin, c'est d'une manière intelligente pour vérifier si cet objet uor existe dans la liste visibUtils.Uors avant de l'insérer pour éviter la duplication.

2 objets UOR sont le même objet s'ils ont les mêmes valeurs pour ces 2 champs: SiglaAOO et SiglaUOR

Un L'objet UOR est une classe modèle comme celle-ci:

UOR uor;

foreach (int idUor in visibilitaPostRidistribuzioni)
{
    uor = UorSQL.GetUorFromId(siglaAOO, idUor, dbConfig);

    visibUtils.Uors.Add(uor);
}

Je sais que je peux itérer sur la liste visibUtils.Uors et vérifiez si dans cette liste existe un objet ayant la même valeur de champs SiglaAOO et SiglaUOR si l'objet courant que je dois insérer.

Mais. ..existe d'une manière plus intelligente? (peut-être quelque chose lié à l'expression lambda)


2 commentaires

Utilisez . Dans tous les cas, vous devez parcourir la liste. Si vous voulez une fonction n log n , vous devez utiliser un Dictionnaire


Vous avez déjà remplacé GetHasCode et Equals, donc c'est très bien. Vous pouvez ensuite utiliser List.Contains , mais ce serait exactement" itérer sur la liste visibUtils.Uors et vérifier ". Une manière plus intelligente consiste à utiliser un hashset au lieu d'une liste, où Add renverrait simplement false si l'objet est déjà présent.


3 Réponses :


1
votes

Modifiez ceci comme suit:

foreach (int idUor in visibilitaPostRidistribuzioni)
{
    var uor = UorSQL.GetUorFromId(siglaAOO, idUor, dbConfig);
    if(!visibUtils.Uors.Any(a => a.Equals(uor))
    {
        visibUtils.Uors.Add(uor);
    }
}


2 commentaires

C'est uor qui ne doit pas être présent, pas idUor .


Réponse modifiée pour refléter cela, utilisant désormais les égales déjà implémentées



3
votes

Comme vous avez défini GetHashCode et Equals , il est préférable d'utiliser HashSet plutôt que List . Parce que HashSet vérifiera l'existence avec une complexité O (1) , tandis que List - avec O (n) .

var interimSet = new HashSet<UOR>();
foreach (int idUor in visibilitaPostRidistribuzioni)
{
    var uor = UorSQL.GetUorFromId(siglaAOO, idUor, dbConfig);

    interimSet.Add(uor); //which is the same as: if(!interimSet.Contains(uor))interimSet.Add(uor);
}

visibUtils.Uors = interimSet.ToList();


2 commentaires

Vous n'avez même pas besoin de Contient . Add sera déjà ne pas ajouter de doublons.


@GSerg, c'est tout à fait vrai, merci. J'ai amélioré ma réponse



1
votes
    UOR uor;
    foreach (int idUor in visibilitaPostRidistribuzioni)
   {
      var uor = UorSQL.GetUorFromId(siglaAOO, idUor, dbConfig);
      if(!visibUtils.Uors.FirstOrDefault(a => a == uor)
      {
        visibUtils.Uors.Add(uor);
      }
  }

0 commentaires