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.
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.
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.
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..
Sure, no problem:
foreach(object item in sequence)
{
if (item == null) continue;
foreach(PropertyInfo property in item.GetType().GetProperties())
{
// do something with the property
}
}
Use Reflection to do this
SomeClass A = SomeClass(...)
PropertyInfo[] properties = A.GetType().GetProperties();
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());
}