0

I know it's very strange but I don't find another way to say it. Please see the image below count list

enter image description here

The output is 1 and always it's the same!

I really don't understand what happend here. Can anyone explain to me?

chue x
  • 18,573
  • 7
  • 56
  • 70
Cristhian Boujon
  • 4,060
  • 13
  • 51
  • 90
  • 1
    Does `TodasMediciones` contain 4 of the same value? – JLRishe Mar 02 '13 at 02:55
  • What is the type of `Mediciones`? Why do you think the foreach loop doesn't finish? Use the debugger to step through the execution of the loop. In particular, see if the `if` condition triggers in each loop iteration. – Michael Petrotta Mar 02 '13 at 02:56
  • output to the console a statement like "Loop Ended" at the end of the loop. That's the easiest way to test whether the loop ends or not. – Nabou Mar 02 '13 at 03:03
  • `TodasMediciones` does not contain the same values. – Cristhian Boujon Mar 02 '13 at 03:15
  • Can you try moving i += 1; Console.WriteLine(i); outside the if to see how many times it loops? – Divi Mar 02 '13 at 06:12

5 Answers5

1

Just a couple of observations on your Modelo and Medicion classes:

public class Modelo<T>
{
    // 1) note PROTECTED set on Id
    public virtual int Id { get; protected set; }

    public override bool Equals(object obj)
    {
        ...
        // 2) comparison is based on Id
        return (this == obj || this.Id == specificOject.Id);
    }
    ...
}

public class Medicion : Modelo<Medicion> {...}
  1. The Id member is defined as protected set.
  2. The Equals method defines two objects as the same if the Id in both are the same.

Are you setting the Id of your Medicion objects anywhere? If not, they are likely to all be 0. If all the Ids are the same, this makes all your objects look the same (your equality definition is based on Id).

Therefore, Mediciones.Contains will always be true after the first object is added. You don't provide any info on Mediciones, but I am assuming here that it is a standard List with no overrides.

chue x
  • 18,573
  • 7
  • 56
  • 70
0

One of those intellisense dialogs is showing you TodasMediciones. The other is showing you Mediciones. These are not the same value.

SecurityMatt
  • 6,593
  • 1
  • 22
  • 28
0

See Modify List.Contains behavior

You're going to want to implement IEquatable<T> in your Medicion.

Community
  • 1
  • 1
Dustin Kingen
  • 20,677
  • 7
  • 52
  • 92
  • Good call, but you'd think the default implementation would use a reference comparison, and therefore trigger the `if` condition all four times through the loop, for each of the four different objects in the list. – Michael Petrotta Mar 02 '13 at 03:01
  • @MichaelPetrotta I'm pretty sure the default `List` behavior when you `Add` an object is to copy it. – Dustin Kingen Mar 02 '13 at 03:03
  • Well, copy the reference to the object. It doesn't do a deep copy. There are four objects he's adding from `TodasMediciones` to `Mediciones`. I'd think that the `Contains` would return false for each new item. – Michael Petrotta Mar 02 '13 at 03:11
0

I don't understand what is your problem. The loop loops on TodasMediciones which is a List. The second debugger is on Mediciones. Both are different objects.

Nikhil Agrawal
  • 47,018
  • 22
  • 121
  • 208
0

Well I'm wrong. The problem (I don't know why) is !Mediciones.Contains(m). The first time is false and in the next iterations is true. I change method as follow

public virtual void AddMediciones(List<Medicion> TodasMediciones)
        {
            int i = 0;
            foreach (Medicion m in TodasMediciones)
            {
                Console.WriteLine(Mediciones.Contains(m));
                Console.WriteLine(m.Valor);
                Console.WriteLine("-------------------------------------------");
                if (!Mediciones.Contains(m))
                {
                    Mediciones.Add(m);
                }
            }
        }

Their output is:

False
1
-------------------------------------------
True
2
-------------------------------------------
True
3
-------------------------------------------
True
4
-------------------------------------------

Here is the Medicion definition:

public class Medicion : Modelo<Medicion>
    {
        public virtual DateTime Fecha { get; set; }
        public virtual decimal Valor { get; set; }
        public virtual Indicador Indicador { get; set; }
    }
}

And their parent definition

public class Modelo<T>
{
    public virtual int Id { get; protected set; }

    public override bool Equals(object obj)
    {
        if (obj == null || obj.GetType() != this.GetType())
        {
            return false;
        }

        Modelo<T> specificOject = (Modelo<T>)obj;
        return (this == obj || this.Id == specificOject.Id);
    }

    public override int GetHashCode()
    {
        return Id.GetHashCode() ^ 5;
    }
}
Cristhian Boujon
  • 4,060
  • 13
  • 51
  • 90