Is there a generic method to iterate and print a values in an unknown collection?

一个人想着一个人 提交于 2019-12-05 06:02:07
Markus Johnsson

You could implement Print like this:

static void Print<T>(IEnumerable<T> items)
{
    var props = typeof(T).GetProperties();

    foreach (var prop in props)
    {
        Console.Write("{0}\t", prop.Name);
    }
    Console.WriteLine();

    foreach (var item in items)
    { 
        foreach (var prop in props)
        {
            Console.Write("{0}\t", prop.GetValue(item, null));
        }
        Console.WriteLine();
    }
}

It simply loops over each property of the class to print the name of the property, then prints over each item and for each item it prints the values of the properties.

I would argue that you should use generics here (as opposed to suggestions in other answers); you want the items in the collection to be of a single type so that you can print table headers.

For table formatting you can check the answers to this question.

Override the object's ToString() method to include all the information you would like to display, and then simply call it whenever you like. No need for expressions or generics.

If you don't know what type - i.e. it could be any type - then the best option is to use reflection. That's a good solution. Why do you feel it's not a good solution?

This example caches a Print method for you for performance using Expressions:

    class MyObject
    {
        public int Property1 { get; set;}
        public string Property2 { get; set; }
    }
    class MyOtherObject
    {
        public int Property3 { get; set; }
        public string Property4 { get; set; }
    }
    static void Main(string[] args)
    {
        Array.ForEach(new[] 
        { 
            new MyObject { Property1 = 1, Property2 = "P" },
            new MyObject { Property1 = 2, Property2 = "Q" } 
        }, Print);
        Array.ForEach(new[]
        {
            new MyOtherObject { Property3 = 3, Property4 = "R" },
            new MyOtherObject { Property3 = 4, Property4 = "S" } 
        }, Print);
        Console.ReadKey();
    }
    static void Print<T>(T item)
    {
        ObjectPrinter<T>.PrintAction(item, Console.Out);
    }
    static class ObjectPrinter<T>
    {
        public static readonly Action<T, TextWriter> PrintAction = CreatePrintAction();
        private static Action<T, TextWriter> CreatePrintAction()
        {
            ParameterExpression item = Expression.Parameter(typeof(T), "item");
            ParameterExpression writer = Expression.Parameter(typeof(TextWriter), "writer");
            var writeLineMethod = typeof(TextWriter).GetMethod("WriteLine", BindingFlags.Public | BindingFlags.Instance, null, new[] { typeof(string) }, null);
            var concatMethod = typeof(string).GetMethod("Concat", BindingFlags.Public | BindingFlags.Static, null, new[] { typeof(object), typeof(object) }, null);
            var writeDashedLine = Expression.Call(
                writer,
                writeLineMethod,
                Expression.Constant(
                    new String('-', 50)
                )
            );
            var lambda = Expression.Lambda<Action<T, TextWriter>>(
                Expression.Block(
                    writeDashedLine,
                    Expression.Block(
                        from property in typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance)
                        where property.GetGetMethod().GetParameters().Length == 0
                        select Expression.Call(
                            writer,
                            writeLineMethod,
                            Expression.Call(
                                null,
                                concatMethod,
                                Expression.Constant(
                                    property.Name + ":"
                                ),
                                Expression.Convert(
                                    Expression.Property(
                                        item,
                                        property
                                    ),
                                    typeof(object)
                                )
                            )
                        )
                    ),
                    writeDashedLine
                ),
                item,
                writer
            );
            return lambda.Compile();
        }
    }
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!