0

I have a class called population which is basically a collection of chromosomes. I need to implement a property to get the higher ranked chromosome in the population.

nevertheless, I got the error system out of range. I would like to know what I'm doing wrong. Any clue or idea will be very helpful.

The Class: public class Population<T> : List<T> inherence from List<T> which is the one I used to Add and creates the population class.

public class Population<T> : List<T>
{
    private List<Chromosome> population;
    private int count;

    public Chromosome Higher()
    {
        return population.OrderBy(chr => chr.Fitness).ToList()[population.Count - 1];
    }

    public Population(int sizePopulation)
    {
        count = sizePopulation;
        population = new List<Chromosome>(sizePopulation);
    }
 }

This is how the class is implemented:

   Population<Chromosome> pop = new Population<Chromosome>(sizePop); 

   for (int i = 0; i < sizePop; i++)
            pop.Add(new Chromosome(9, 97, 122));

At some point here, the chromosomes are evaluated and their Fitness properties is defined.

   Chromosome best = pop.Higher(); //get the error out of range.

I should expect a chromosome as a return but I get the

System.ArgumentOutOfRangeException: 'Index was out of range. Must be non-negative and less than the size of the collection. Parameter name: index'.

population count is 0.

Draken
  • 3,134
  • 13
  • 34
  • 54
  • 1
    The problem is with this part of the code `.ToList()[population.Count - 1]`. As the error indicates, the population count is 0, so this will give an index of `-1` which is clearly out of range (hence the exception). – Martin Sep 06 '19 at 10:59
  • 1
    Btw your problem may be where you do `pop.Add(...)` you are adding to the generic List that `Population` inherits from and **not** `population` which is the list of chromosomes – Martin Sep 06 '19 at 11:01
  • 2
    You haven't shown us the `Add` method. If it is the one that was inherited from `List`, note that you have 2 lists in play here, you have the object itself, which inherits from list, and you have the `pop` list inside the class. You added elements to the object itself, not to `pop`. – Lasse V. Karlsen Sep 06 '19 at 11:01
  • 1
    Why is Population generic? You are not using the generic parameter. – Palle Due Sep 06 '19 at 11:02
  • Thanks Martin, but Why? is the constructor not enough to construct the Population object? – carlosdelab Sep 06 '19 at 11:03
  • 1
    You're both inheriting from, and composing your object of a `List`. Only do one, not the other. (Hint: composing is the better choice here!) So get rid of `: List` and implement your own `Add` method which adds to the population list – Jamiec Sep 06 '19 at 11:04
  • 1
    @carlosdelab See Jamiec's answer below which address the problem I pointed out in my comment – Martin Sep 06 '19 at 11:08
  • Agree with @Jamiec here. have a look at [this](https://stackoverflow.com/a/21694054/3276027). Inheriting from `List` is usually the wrong choice. In your case more confusion is added having Population both inheriting and having a List`` – Gian Paolo Sep 06 '19 at 11:12

1 Answers1

3

You're both inheriting from List and composing your object of a List! Inheriting is probably the wrong thing here, you should be using composition.

You can also make use of Last() to get the final item from the list after ordering.

public class Population
{
    private List<Chromosome> population;

    public Population(int sizePopulation)
    {
        population = new List<Chromosome>(sizePopulation);
    }

    public void Add(Chromosome chromosome)
    {
        population.Add(chromosome);
    }

    public Chromosome Higher()
    {
        return population.OrderBy(chr => chr.Fitness).Last();
    }
 }

And

Population pop = new Population(sizePop); 
for (int i = 0; i < sizePop; i++)
        pop.Add(new Chromosome(9, 97, 122));
Jamiec
  • 133,658
  • 13
  • 134
  • 193
  • Thanks Jamiec, It means I will need to implement other propierties by hand, like Count for example or indexing with []? – carlosdelab Sep 06 '19 at 11:13
  • @carlosdelab yes, that's pretty normal for a List-y sort of class which isnt actually a list. ie, a Population doesnt have an `is-a` relationship with a list, it has a `has-a` relationship. – Jamiec Sep 06 '19 at 11:14
  • Or ... you could remove the `pop` field, but my advice would be to go for composition. – Lasse V. Karlsen Sep 06 '19 at 11:15