【问题标题】:Convert List<Objects> to List<String> based on property fed in at runtime根据运行时输入的属性将 List<Objects> 转换为 List<String>
【发布时间】:2015-09-04 14:29:31
【问题描述】:

所以我有一个Objects 的列表,例如:

var animals = new List<Animal>() //add Animals`

我知道我可以将这些从 This Question 转换为 strings,例如:

List<Animal> animals = new List<Animal>();
List<string> strings = animals.Select(a => (string)a).ToList();

但是我想根据我在运行时作为string 输入的属性从animals 列表中获取List&lt;string&gt;

例如:

private List<string> GetList(string property)
{
    return animals.Select(x => filterByReflection(property)).ToList();
}

所以我可以打电话:

var names = GetList("Name");
var types = GetList("Type");
var ages = GetList("Age");

这可能吗?

【问题讨论】:

    标签: c# list reflection


    【解决方案1】:

    完整的工作示例:

    class Program
    {
        static List<Animal> animals = new List<Animal>();
    
        static void Main(string[] args)
        {
            animals.Add(new Animal() { Age = 3, Name = "Terry", Type = "Tiger" });
            animals.Add(new Animal() { Age = 1, Name = "Bob", Type = "Badger" });
            animals.Add(new Animal() { Age = 7, Name = "Alfie", Type = "Dog" });
    
            GetList("Age").ForEach(Console.WriteLine);
    
            Console.Read();
        }
    
        public static List<string> GetList(string property)
        {
            return animals.Select(o => o.GetType().GetProperty(property).GetValue(o).ToString()).ToList();
        }
    }
    
    class Animal
    {
        public string Name { get; set; }
        public string Type { get; set; }
        public int Age { get; set; }
    }
    

    【讨论】:

      【解决方案2】:

      是的,是这样的:

      private List<string> GetList(string property)
      {
          return animals.Select(x => GetProperty(x, property)).ToList();
      }
      
      private static string GetProperty(Animal animal, string property)
      {
          Type type = typeof(Animal);
          PropertyInfo propertyInfo = type.GetProperty(property);
          return (string)propertyInfo.GetValue(animal);
      }
      

      【讨论】:

        【解决方案3】:

        所以我发现我可以使用这些方法通过Reflection获取PropertyInfo

        private string GetValue(object item, string propString)
            {
                if (item != null)
                {
                    if (!string.IsNullOrEmpty(propString))
                    {
                        try
                        {
                            var property = GetProperty(item.GetType().GetTypeInfo(), AutoCompleteSourceMember);
                            if (property != null)
                            {
                                var value = property.GetValue(item);
                                if (value != null)
                                {
                                    return value.ToString();
                                }
        
                            }
                            return string.Empty;
        
                        }
                        catch (Exception ex)
                        {
                            return string.Empty;
                        }
                    }
                    else
                    {
                        return item.ToString();
                    }
                }
                return string.Empty;
            }
        
            private static PropertyInfo GetProperty(TypeInfo typeInfo, string propertyName)
            {
                var propertyInfo = typeInfo.GetDeclaredProperty(propertyName);
                if (propertyInfo == null && typeInfo.BaseType != null)
                {
                    propertyInfo = GetProperty(typeInfo.BaseType.GetTypeInfo(), propertyName);
                }
                return propertyInfo;
            }
        

        并像这样使用它:

        private List<string> GetList(string property)
        {
            return animals.Select(x => GetValue(x,property)).ToList();
        }
        

        【讨论】:

          【解决方案4】:

          既然你知道他们是strings,你可以直接将filterByReflection的结果转换为string

          private List<string> GetList(string property)
          {
              return animals.Select(x => (string)filterByReflection(property)).ToList();
          }
          

          更一般地,您可以将此方法设为通用:

          private List<T> GetList<T>(string property)
          {
              return animals.Select(x => (T)filterByReflection(property)).ToList();
          }
          

          当然,如果您传入的属性名称在第一种情况下不返回string,在第二种情况下不返回T,您将在运行时得到InvalidCastException

          【讨论】:

            【解决方案5】:

            一个通用函数:

            public static class Extensions
            {
                public static IEnumerable<P> SelectProperty<T, P>(this IEnumerable<T> source, string propertyName)
                {
                    var selector = (Func<T, P>)Delegate.CreateDelegate(typeof(Func<T, P>), typeof(T).GetProperty(propertyName).GetGetMethod());
                    return source.Select(selector);
                }
            }
            

            及用法:

            private List<string> GetList(string property)
            {
                return animals.SelectProperty<Animal, string>(property).ToList();
            }
            

            这是最快的基于反射的方法,因为反射只进行一次,而不是像其他答案那样针对每个项目进行。

            【讨论】:

              猜你喜欢
              • 2021-09-17
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2021-02-28
              • 1970-01-01
              • 2021-01-13
              • 1970-01-01
              相关资源
              最近更新 更多