Recursive method on array of a recursive type duplicates values

178 Views Asked by At

I'm messing around with recursive types to get used to them and learn, I've written the following class:

public class ParameterData
{
    public string[] Values { get; set; } = new string[0];
    public ParameterData[] NestedValues { get; set; } = new ParameterData[0];

    public bool IsNested { get => NestedValues.Length > 0; }
    public int Length { get => IsNested ? NestedValues.Length : Values.Length; }

    public dynamic this[int pos]
    {
        get
        {
            if (IsNested) return NestedValues[pos];
            else return Values[pos];
        }
        set
        {
            if (IsNested) NestedValues[pos] = value;
            else Values[pos] = value;
        }
    }

    public static implicit operator ParameterData[](ParameterData value)
    {
        if (Object.ReferenceEquals(null, value))
            throw new ArgumentNullException("value");

        return value.NestedValues;
    }
}

This seems to work properly, according to the values shown in the debugger at least.

I've tried to use them, in an attempt to see where recursive types can be useful, but I've run into a problem, a "simple" loop runs 2 times over the nested items, I can't figure out if it's due to bad object design or bad loop coding. Could you give me some insight?

The code:

[TestMethod()]
public void LoadingWindowTest()
{
        ParameterData[] temp = new ParameterData[]{
            new ParameterData {Values=new string[]{ "Titulo" } },
            new ParameterData {Values=new string[]{ "Autor1" , "Autor2" } },
            new ParameterData {NestedValues=new ParameterData[]{
                new ParameterData {NestedValues=new ParameterData[]{
                    new ParameterData {Values = new string[]{"Hola"} },
                    new ParameterData {Values = new string[]{"Don", "Pepito"} }
                } },
                new ParameterData {Values = new string[]{"Outta Nest"} }
            } },
            new ParameterData {Values=new string[]{ "Last" } }
        };

        print(temp);
}

private void print(ParameterData[] data, int indent = 0)
{
        for (int i = 0; i < data.Length; i++)
        {
            for (int x = 0; x < data[i].Length; x++)
            {
                if (data[i][x] is string) Console.WriteLine("" + indent + data[i][x]);
                else print(data[i], indent + 1);
            }
        }
}

This is the output:

enter image description here

EDIT: To clarify the issue: every line that starts with a value greater than 0 it's duplicated. Furthermore it's exponential, the lines are duplicated by 2^n where n it's the line's "level".

1

There are 1 best solutions below

0
On BEST ANSWER

As Peter Duniho stated, my issue came from using 2 loops. The following code works as intended:

private void print(ParameterData[] data, int indent = 0)
    {
        for (int i = 0; i < data.Length; i++)
        {
            if (data[i].IsNested) print(data[i], indent + 1);
            else
            {
                for (int x = 0; x < data[i].Length; x++) Console.WriteLine("" + indent + data[i][x]);
            }
        }
    }

The source of my confusion was the fact that I implemented an indexer (for the sake of it) and that created the ilusion of working with a 2D array.

For anyone who might have a similar issue in the future:

  • Don't use indexers(or anything really) where it's not needed
  • An array of a type that contains an array of itself will be n-dimensional, no matter how it looks(this should be obvious, but here I am, having this issue).