c# foreach (property in object)… Is there a simple way of doing this?

前端 未结 9 2020
感情败类
感情败类 2020-11-28 22:10

I have a class containing several properties (all are strings if it makes any difference).
I also have a list, which contains many different instances of the class.

相关标签:
9条回答
  • 2020-11-28 22:30

    A small word of caution, if "do some stuff" means updating the value of the actual property that you visit AND if there is a struct type property along the path from root object to the visited property, the change you made on the property will not be reflected on the root object.

    0 讨论(0)
  • 2020-11-28 22:31

    Your'e almost there, you just need to get the properties from the type, rather than expect the properties to be accessible in the form of a collection or property bag:

    var property in obj.GetType().GetProperties()
    

    From there you can access like so:

    property.Name
    property.GetValue(obj, null)
    

    With GetValue the second parameter will allow you to specify index values, which will work with properties returning collections - since a string is a collection of chars, you can also specify an index to return a character if needs be.

    0 讨论(0)
  • 2020-11-28 22:38

    I looked for the answer to a similar question on this page, I wrote the answers to several similar questions that may help people who enter this page.

    Class List

    List < T > class represents the list of objects which can be accessed by index. It comes under the System.Collection.Generic namespace. List class can be used to create a collection of different types like integers, strings etc. List class also provides the methods to search, sort, and manipulate lists.

    Class with property:

    class TestClss
    {
        public string id { set; get; }
        public string cell1 { set; get; }
        public string cell2 { set; get; }
    }
    var MyArray = new List<TestClss> {
        new TestClss() { id = "1", cell1 = "cell 1 row 1 Data", cell2 = "cell 2 row 1 Data" },
        new TestClss() { id = "2", cell1 = "cell 1 row 2 Data", cell2 = "cell 2 row 2 Data" },
        new TestClss() { id = "3", cell1 = "cell 1 row 2 Data", cell2 = "cell 2 row 3 Data" }
    };
    foreach (object Item in MyArray)
    {
        Console.WriteLine("Row Start");
        foreach (PropertyInfo property in Item.GetType().GetProperties())
        {
            var Key = property.Name;
            var Value = property.GetValue(Item, null);
            Console.WriteLine("{0}={1}", Key, Value);
        }
    }
    

    OR, Class with field:

    class TestClss
    {
        public string id = "";
        public string cell1 = "";
        public string cell2 = "";
    }
    var MyArray = new List<TestClss> {
        new TestClss() { id = "1", cell1 = "cell 1 row 1 Data", cell2 = "cell 2 row 1 Data" },
        new TestClss() { id = "2", cell1 = "cell 1 row 2 Data", cell2 = "cell 2 row 2 Data" },
        new TestClss() { id = "3", cell1 = "cell 1 row 2 Data", cell2 = "cell 2 row 3 Data" }
    };
    foreach (object Item in MyArray)
    {
        Console.WriteLine("Row Start");
        foreach (var fieldInfo in Item.GetType().GetFields())
        {
            var Key = fieldInfo.Name;
            var Value = fieldInfo.GetValue(Item);
        }
    
    }
    

    OR, List of objects (without same cells):

    var MyArray = new List<object> {
        new { id = "1", cell1 = "cell 1 row 1 Data", cell2 = "cell 2 row 1 Data" },
        new { id = "2", cell1 = "cell 1 row 2 Data", cell2 = "cell 2 row 2 Data" },
        new { id = "3", cell1 = "cell 1 row 2 Data", cell2 = "cell 2 row 3 Data", anotherCell = "" }
    };
    foreach (object Item in MyArray)
    {
        Console.WriteLine("Row Start");
        foreach (var props in Item.GetType().GetProperties())
        {
            var Key = props.Name;
            var Value = props.GetMethod.Invoke(Item, null).ToString();
            Console.WriteLine("{0}={1}", Key, Value);
        }
    }
    

    OR, List of objects (It must have the same cells):

    var MyArray = new[] {
        new { id = "1", cell1 = "cell 1 row 1 Data", cell2 = "cell 2 row 1 Data" },
        new { id = "2", cell1 = "cell 1 row 2 Data", cell2 = "cell 2 row 2 Data" },
        new { id = "3", cell1 = "cell 1 row 2 Data", cell2 = "cell 2 row 3 Data" }
    };
    foreach (object Item in MyArray)
    {
        Console.WriteLine("Row Start");
        foreach (var props in Item.GetType().GetProperties())
        {
            var Key = props.Name;
            var Value = props.GetMethod.Invoke(Item, null).ToString();
            Console.WriteLine("{0}={1}", Key, Value);
        }
    }
    

    OR, List of objects (with key):

    var MyArray = new {
        row1 = new { id = "1", cell1 = "cell 1 row 1 Data", cell2 = "cell 2 row 1 Data" },
        row2 = new { id = "2", cell1 = "cell 1 row 2 Data", cell2 = "cell 2 row 2 Data" },
        row3 = new { id = "3", cell1 = "cell 1 row 2 Data", cell2 = "cell 2 row 3 Data" }
    };
    // using System.ComponentModel;  for TypeDescriptor
    foreach (PropertyDescriptor Item in TypeDescriptor.GetProperties(MyArray))
    {
        string Rowkey = Item.Name;
        object RowValue = Item.GetValue(MyArray);
        Console.WriteLine("Row key is: {0}", Rowkey);
        foreach (var props in RowValue.GetType().GetProperties())
        {
            var Key = props.Name;
            var Value = props.GetMethod.Invoke(RowValue, null).ToString();
            Console.WriteLine("{0}={1}", Key, Value);
        }
    }
    

    OR, List of Dictionary

    var MyArray = new List<Dictionary<string, string>>() {
        new Dictionary<string, string>() { { "id", "1" }, { "cell1", "cell 1 row 1 Data" }, { "cell2", "cell 2 row 1 Data" } },
        new Dictionary<string, string>() { { "id", "2" }, { "cell1", "cell 1 row 2 Data" }, { "cell2", "cell 2 row 2 Data" } },
        new Dictionary<string, string>() { { "id", "3" }, { "cell1", "cell 1 row 3 Data" }, { "cell2", "cell 2 row 3 Data" } }
    };
    foreach (Dictionary<string, string> Item in MyArray)
    {
        Console.WriteLine("Row Start");
        foreach (KeyValuePair<string, string> props in Item)
        {
            var Key = props.Key;
            var Value = props.Value;
            Console.WriteLine("{0}={1}", Key, Value);
        }
    }
    

    Good luck..

    0 讨论(0)
  • 2020-11-28 22:43

    Sure, no problem:

    foreach(object item in sequence)
    {
        if (item == null) continue;
        foreach(PropertyInfo property in item.GetType().GetProperties())
        {
            // do something with the property
        }
    }
    
    0 讨论(0)
  • 2020-11-28 22:43

    Use Reflection to do this

    SomeClass A = SomeClass(...)
    PropertyInfo[] properties = A.GetType().GetProperties();
    
    0 讨论(0)
  • 2020-11-28 22:43

    A copy-paste solution (extension methods) mostly based on earlier responses to this question.

    Also properly handles IDicitonary (ExpandoObject/dynamic) which is often needed when dealing with this reflected stuff.

    Not recommended for use in tight loops and other hot paths. In those cases you're gonna need some caching/IL emit/expression tree compilation.

        public static IEnumerable<(string Name, object Value)> GetProperties(this object src)
        {
            if (src is IDictionary<string, object> dictionary)
            {
                return dictionary.Select(x => (x.Key, x.Value));
            }
            return src.GetObjectProperties().Select(x => (x.Name, x.GetValue(src)));
        }
    
        public static IEnumerable<PropertyInfo> GetObjectProperties(this object src)
        {
            return src.GetType()
                .GetProperties(BindingFlags.Public | BindingFlags.Instance)
                .Where(p => !p.GetGetMethod().GetParameters().Any());
        }
    
    0 讨论(0)
提交回复
热议问题