将对象从带有泛型的 propertyinfo getvalue 转换为接口列表

时间:2021-04-16 06:44:47

标签: c# generics reflection

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?
 }
}



我需要在通用属性上编辑接口的数据。 上面的代码应该显示我之后的内容,而不是我是如何做到这一点的。 这个问题似乎没有答案。 C# casting the result of GetValue from PropertyInfo to a generic list

事实证明,如果您知道自己在做什么,则完全有可能。 此外,副本没有描述如何使用财产信息来获得我认为在这个问题中明确提出的问题。所以不是真的重复 也许代码有点讨厌,但它完成了。

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

            }

        }

    }



0 个答案:

没有答案
相关问题