根据运行时输入的 属性 将 List<Objects> 转换为 List<String>
Convert List<Objects> to List<String> based on property fed in at runtime
所以我有一个列表 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();
BUT 我想根据 属性 从 animals
的列表中获取 List<string>
作为 string
在运行时
例如:
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");
这可能吗?
是的,像这样:
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);
}
所以我发现我可以使用这些方法通过 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();
}
因为你知道它们是 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();
}
当然,如果您传入的 属性 名称在第一种情况下不 return 为 string
或在第二种情况下为 T
,您将得到一个InvalidCastException
在 运行 时间。
完整的工作示例:
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; }
}
通用函数:
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();
}
这是最快的基于反射的方法,因为反射只进行一次,而不是像其他答案那样对每个项目进行反射。
所以我有一个列表 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();
BUT 我想根据 属性 从 animals
的列表中获取 List<string>
作为 string
在运行时
例如:
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");
这可能吗?
是的,像这样:
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);
}
所以我发现我可以使用这些方法通过 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();
}
因为你知道它们是 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();
}
当然,如果您传入的 属性 名称在第一种情况下不 return 为 string
或在第二种情况下为 T
,您将得到一个InvalidCastException
在 运行 时间。
完整的工作示例:
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; }
}
通用函数:
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();
}
这是最快的基于反射的方法,因为反射只进行一次,而不是像其他答案那样对每个项目进行反射。