0

I have seen examples (and official ones) for IEnumerator on lists and arrays or dicts, but I have a different problem. I have classes with properties, how may I implement the IEnumerable and IEnumerator in that case?

My properties classes are:

public class standardMessage
{
    public messageProperties message { get; set; }
    public messageFlag flag { get; set; }
}

public class messageProperties
{
    public string messageSubject { get; set; }
    public string messageBody { get; set; }
}

public class messageFlag
{
    public Boolean flagImportant { get; set; }
    public Boolean flagPersonal { get; set; }
}

And this is the Program:

public class Program
{
    static void Main(string[] args)
    {
        standardMessage myMessage = new standardMessage();

        myMessage.message = new messageProperties
        {
            messageSubject = "Greetings",
            messageBody = "Happy Weekend"
        };

        myMessage.flag = new messageFlag
        {
            flagImportant = false,
            flagPersonal = true
        };

        //how do I iterate through all properties, without knowing how many are there, instead of writing this worm line of code?
        Console.WriteLine(myMessage.message.messageSubject.ToString() + "\r\n" + myMessage.message.messageBody.ToString() + "\r\n" + myMessage.flag.flagImportant.ToString() + "\r\n" + myMessage.flag.flagPersonal.ToString());
        Console.ReadLine();
    }
}
4
  • 1
    You probably in this case just want to override the ToString method of the classes. Commented Jan 7, 2020 at 18:15
  • 1
    Well, you already have the similar question C# how to implement IEnumerable for nested classes Commented Jan 7, 2020 at 18:53
  • Using reflection you can get an IEnumerable of all of a classes properties. You can then iterate through the properties to get any properties nested within them the same way like iterating through any other tree structure. Commented Jan 7, 2020 at 19:07
  • @Pavel Anikhouski Thank you for pointing out the other solution; however, it does not implement IEnumerable (despite the fact that properties were singletons, I was looking for a List solution but anyhow) and more important, when I implemented i found out that it does not return the "child" properties. For example, for our question here, I was hoping not just "see" the "message" and "flag" but also the "messageSubject" and "messageBody" within the "message" - and same for "flagImportant" and "flagPersonal" within "flag" of the standardMessage. Commented Jan 8, 2020 at 9:11

2 Answers 2

1

If you want a production-grade way of printing your objects as a formatted string, you need to go and override ToString in all your classes to return whatever format you want.

However, if you just want to print the things on screen for debugging or logging purposes, why not JSON?

public static string ToJson(object @object) =>
    System.Text.Json.JsonSerializer.Serialize(@object, new JsonSerializerOptions{WriteIndented = true});
Console.WriteLine(ToJson(myMessage));

Prints

{
  "message": {
    "messageSubject": "Greetings",
    "messageBody": "Happy Weekend"
  },
  "flag": {
    "flagImportant": false,
    "flagPersonal": true
  }
}

Quick and dirty, but quick and working.

Sign up to request clarification or add additional context in comments.

4 Comments

Thank you very much, may I ask, I get an error for System.Text.Json (as Json doesnt exist in System.Text) - your advice?
@Nick System.Text.Json is from .NET Core 3.0, if you're using Framework or an older version of Core, get the System.Text.Json NuGet package
Thank you, it worked as per your advice. I was just wondering if I can do it without Json (problem installing Nuget in another environment, absolutely nothing wrong with your answer..)
@Nick You can write a serializer yourself, but that's cumbersome. You're probably better off just overriding ToString yourself at that point.
0

I made a very primitive object to json converter. I wouldn't use this in production and it's about 30% slower than Newtonsoft but it get's the job done.

private static string PrintObject(object obj, int depth = 1)
{
    var type = obj.GetType();
    if (type.IsPrimitive || type == typeof(Decimal) || type == typeof(String))
        return "\"" + obj.ToString() + "\"";
    var props = type.GetProperties();
    string ret = "";
    for (var i = 0; i < props.Length; i++)
    {
        var val = props[i].GetValue(obj);
        ret += new string('\t', depth) + "\"" + props[i].Name + "\":" + PrintObject(val, depth + 1);
        if (i != props.Length - 1)
            ret += "," + Environment.NewLine;
    }

    return ("{" + Environment.NewLine + ret + Environment.NewLine + new string('\t', depth - 1) + "}").Replace("\t", "  ");
}

Gives the result

{
  "message":{
    "messageSubject":"Greetings",
    "messageBody":"Happy Weekend"
  },
  "flag":{
    "flagImportant":"False",
    "flagPersonal":"True"
  }
}

3 Comments

Thank you very much, I put it in Main without the private static and worked as you describe. May I ask - if I may - for a thing? I don't usually know the depth, how could I modify to search up to the last level of nested properties? Thank you very much!!
Don't put anything for the depth parameter. It will start out at 1 when you call it and recursively increment every time it's called. If you want to print a nested object then just call PrintObject(myMessage.flag);
If this solved your issue could you mark it as answered? Thank you!

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.