0
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());
                    }
                }

            }

        }

    }



Gauthier
  • 1,251
  • 10
  • 25

0 Answers0