1

I have the following class structure (simplified) :

public class MyBaseType
{
    public string InstanceName { get; set; }
    public List<MyBaseType> MyBaseTypeList = new List<MyBaseType>();
    public List<MyObject1> MyObject1List = new List<MyObject1>();
    public List<MyObject2> MyObject2List = new List<MyObject2>();
    // Other properties
}

public class MyObject1
{
    public string SimpleName { get; set; }
    public string Name { get; set; }
    // Other properties
}

public class MyObject2
{
    public string SimpleName { get; set; }
    public string Name { get; set; }
    // Other properties
}

As you can see, an instance of MyBaseType can contain a list of instances of the same type as well as a list of MyObject1 and MyObject2.

A typical use for me of this would render a structure as shown here :

MyBaseType instance1
|-> InstanceName = "instance1"
|
|-> MyBaseType instance2
|   |-> InstanceName = "instance2"
|   |
|   |-> MyObject1 object1_1
|   |   |-> SimpleName = "object1_1"
|   |-> MyObject2 object2_1
|   |   |-> SimpleName = "object2_1"
|
|-> MyBaseType instance3
|   |-> InstanceName = "instance3"
|   |
|   |-> MyObject1 object1_2
|   |   |-> SimpleName = "object1_2"
|   |-> MyObject2 object2_2
|   |   |-> SimpleName = "object2_1"
|
|-> MyObject1 object1_3
|   |-> SimpleName = "object1_3"
|-> MyObject2 object2_3
|   |-> SimpleName = "object2_3"

Visibly, this structure can get quite complex.

What I need to do however is to recursively dive into the MyBaseType list, track all the InstanceName values as I go to finally append the combined string with the SimpleName of either MyObject1 or MyObject2 to the Name property of either object.

Following the above structure example, the names would be :

MyObject1 object1_1 : instance1_instance2_object1_1
MyObject1 object2_1 : instance1_instance2_object2_1
MyObject1 object1_2 : instance1_instance3_object1_1
MyObject1 object2_2 : instance1_instance3_object1_2
MyObject1 object1_3 : instance1_object1_3
MyObject1 object2_3 : instance1_object2_3

I am struggling to find a way to recursively iterate through the List<MyBaseType> AND keep track of the name being constructed.

7
  • I am sorry although you have gone through quite the trouble in order for this to make sense. This does not make sense at least to me. What is your end goal? Why do you need this to happen recursively? An overall what? Commented Jun 15, 2020 at 14:25
  • Recursively because since an instance of MyBaseType can contain a list of MyBaseType instances, you will necessarily go through a recursion to reach an instance where said list is empty Commented Jun 15, 2020 at 14:30
  • Well, this does not need to happen recursively. You can iterate your list with a for loop. Also if you want to make sure a property of base type is set. You can force its instantiation through a constructor if you have to. I think you are a bit confused with properties that self reference the object. Like a node class from a linked list. The answer provided is just a for loop but hidden. You have to read what linq is all about. Commented Jun 15, 2020 at 14:38
  • It's quite possible you are right. I'll take a closer look. I assumed recursion since I don't know how many times I will be adding an instance to another instance's list. Could be 100 times Commented Jun 15, 2020 at 14:40
  • 1
    Thanks a lot ! I'll look into it and should hopefully have a solution soon. Commented Jun 15, 2020 at 14:48

3 Answers 3

1

Try something like this :

public class MyBaseType
    {
        public string InstanceName { get; set; }
        public List<MyBaseType> MyBaseTypeList = new List<MyBaseType>();
        public List<MyObject1> MyObject1List = new List<MyObject1>();
        public List<MyObject2> MyObject2List = new List<MyObject2>();

        public string GetName()
        {
            return $"{InstanceName}-{string.Join('-',MyBaseTypeList.Select(q => q.GetName()))}";
        }
    }
Sign up to request clarification or add additional context in comments.

2 Comments

I am getting a "Cannot convert from System.Generic.Collection.IEnumerable<String> to String" error... Also, how does this method manage to set the name for the MyObject1 and MyObject2 instances ?
Managed to get it working but the result is just a concatenation of all the InstanceName of the particular instance. There is no seperation by instance which, if you look at the question, is what I need....
1

Following the comments given by panoskarajohn (who I thank) and everyone else that has contributed, I have come up with the following solution which does what I expected :

public void GenerateNames(string input)
{
    if (!IsEmpty(MyBaseTypeList))
    {
        foreach (MyBaseType mbt in MyBaseTypeList)
        {
            mbt.GenerateNames(input + "_" + mbt.InstanceName);
        }
    }
    else
    {
        foreach (MyObject1 mo1 in MyObject1List)
        {
            mo1.Name = input + "_" + mo1.SimpleName;
        }
        foreach (MyObject2 mo2 in MyObject2List)
        {
            mo2.Name = input + "_" + mo2.SimpleName;
        }
    }
}

Comments

1

you could try to apply the decorator pattern where you pass your base identifier.

Add this method to your MyBaseType Class;

public Dictionary<string,MyObject1> GenerateString(string bString)
    {
        if(bString != null) bString += "_";

        Dictionary<string, Object> dict = new Dictionary<string, Object>();
        if (MyBaseTypeList.DefaultIfEmpty() != null)
        {
             dict = this.MyBaseTypeList.Select(s => s.GenerateString(bString + InstanceName)).SelectMany(d => d).ToDictionary(e => e.Key, e => e.Value);
        }

        MyObject1List.ForEach(myObject => dict.Add(bString + InstanceName + "_" + myObject.SimpleName,myObject));
        MyObject2List.ForEach(myObject => dict.Add(bString + InstanceName + "_" + myObject.SimpleName,myObject));

        return dict;
    }

this way u get a dictonary of all the objects with their path as a key.

all you need is to call the function in the base object with a null as parameter. (instance1)

5 Comments

I like this, I will test it to see if it fits what I need ! (Note that although MyObject1 and MyObject2 seem the same, they really are not. They have vastly different properties other than the ones I actually write. I did specify this I think)
do they both have SimpleName in common ? if so u can wrap them in a class that contains just SimpleName, this way u can save any class.
I see the idea yes, unfortunately, the class structure I'm working with is more complex than I can show in a question here and I can't join the two classes in any way. There is redundancy due to that but it's something I know how to sort at a later date.
Well we can still use 2 completly different classes we can just use Object as a wrapper in the dictonary and identify each object by their respective identifiers
Changed code so u can still use any object for your list

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.