interface blah
{
int status;
}
class B : blah
{
public int status;
}
class A : blah
{
public int status;
public List<B> items;
}
var the_a = new A() { items = new List<B>() { new B() { status = 5; } } };
// this gets passed around and eventually gets to a generic function
// that is trying to update status on the item and any children that might also have the interface blah
PropertyInfo pinfo = null; /* the PropertyInfo of items on class A */
// this function
private function update<T>(T data) where T : blah
{
if (pinfo.PropertyType.IsGenericType && pinfo.PropertyType.GetGenericTypeDefinition() == typeof(List<>))
{
// i now know my generic has a list, and that the list is of type List<blah>
// however .net standard 2.0 doesn't allow casting as IList;
// you have to pass a type
// however it also wont allow cast to IList<blah>
// how do a get either IList<blah> or even a list of objects
// something i can loop through?
var temp_object = pinfo.GetValue(data);
// how does one iterate or cast this to a iterable list of interface blah?
}
}
I need to edit the data of an interface on a property of a generic. The above code should show what im after, not exactly how i got to that point though. This question doesnt seem to answer it. C# casting the result of GetValue from PropertyInfo to a generic list
Well as it turns out is totally possible if you know what your doing. Also the duplicate doesn't describe how to use property info to get what i believe was clearly asked in this question. so not really a duplicate Perhaps the code is a little obnoxious but it gets it done.
public class totally_possible
{
private Type i_blah_type = typeof(i_blah);
//private Type i_enumorator = typeof(IEnum)
public interface i_blah
{
DateTime last_updated { get; set; }
}
public class north_object : i_blah
{
public bool something;
public DateTime last_updated { get; set; }
}
public class east_object : i_blah
{
public bool something;
public DateTime last_updated { get; set; }
public north_object random_data { get; set; }
}
public class compass_object : i_blah
{
public string ignore_this;
public int something_unneeded;
public List<north_object> northlist { get; set; } = new List<north_object>();
public List<east_object> eastlist { get; set; } = new List<east_object>();
public DateTime last_updated { get; set; }
}
public void check_all_the_things()
{
var n = DateTime.Now;
var list = new List<object>()
{
new north_object() { last_updated = n, something = true },
new east_object() { last_updated = n, something = false, random_data = new north_object() { last_updated = n, something = true }},
new compass_object() { last_updated = n, something_unneeded = 4, ignore_this = "super",
northlist = new List<north_object>()
{
new north_object() { last_updated = n, something = true },
new north_object() { last_updated = n, something = false }
},
eastlist = new List<east_object>()
{
new east_object() { last_updated = n, something = true , random_data = new north_object() { last_updated = n, something = true }},
new east_object() { last_updated = n, something = false , random_data = new north_object() { last_updated = n, something = true }},
}
}
};
Thread.Sleep(2000);
update_object(list);
}
public void update_object<T>(T item, DateTime time)
where T : i_blah
{
item.last_updated = time;
}
public void update_object<T>(List<T> items)
where T : class
{
var new_time = DateTime.Now;
if (items.Count == 0) return;
foreach (var item in items)
{
var item_type = item.GetType();
var prop_list = item_type.GetProperties();
if (!i_blah_type.IsAssignableFrom(item_type))
continue;
if (!(item is i_blah blah_interface))
continue;
blah_interface.last_updated = DateTime.Now;
foreach (var property in prop_list)
{
if (i_blah_type.IsAssignableFrom(property.GetType()))
update_object(property.GetValue(item) as i_blah, new_time);
else if (property.PropertyType.IsGenericType && property.PropertyType.GetGenericTypeDefinition() == typeof(List<>) &&
property.GetValue(item) is object untyped_list &&
property.PropertyType.GetMethod("GetEnumerator") is System.Reflection.MethodInfo method &&
method.Invoke(untyped_list, new object[] { }) is IEnumerator<object> enumerator)
{
do
{
if (!(enumerator.Current is i_blah instance))
continue;
instance.last_updated = DateTime.Now;
}
while (enumerator.MoveNext());
}
}
}
}
}