LINQ按名称选择属性 [英] LINQ select property by name
问题描述
我正在尝试在LINQ select语句中使用变量.
I'm attempting to use a variable inside of a LINQ select statement.
这是我现在正在做的一个例子.
Here is an example of what I'm doing now.
using System;
using System.Collections.Generic;
using System.Linq;
using Faker;
namespace ConsoleTesting
{
internal class Program
{
private static void Main(string[] args)
{
List<Person> listOfPersons = new List<Person>
{
new Person(),
new Person(),
new Person(),
new Person(),
new Person(),
new Person(),
new Person(),
new Person(),
new Person(),
new Person(),
new Person()
};
var firstNames = Person.GetListOfAFirstNames(listOfPersons);
foreach (var item in listOfPersons)
{
Console.WriteLine(item);
}
Console.WriteLine();
Console.ReadKey();
}
public class Person
{
public string City { get; set; }
public string CountryName { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public Person()
{
FirstName = NameFaker.Name();
LastName = NameFaker.LastName();
City = LocationFaker.City();
CountryName = LocationFaker.Country();
}
public static List<string> GetListOfAFirstNames(IEnumerable<Person> listOfPersons)
{
return listOfPersons.Select(x => x.FirstName).Distinct().OrderBy(x => x).ToList();
}
public static List<string> GetListOfCities(IEnumerable<Person> listOfPersons)
{
return listOfPersons.Select(x => x.FirstName).Distinct().OrderBy(x => x).ToList();
}
public static List<string> GetListOfCountries(IEnumerable<Person> listOfPersons)
{
return listOfPersons.Select(x => x.FirstName).Distinct().OrderBy(x => x).ToList();
}
public static List<string> GetListOfLastNames(IEnumerable<Person> listOfPersons)
{
return listOfPersons.Select(x => x.FirstName).Distinct().OrderBy(x => x).ToList();
}
}
}
}
我的GetListOf ...方法具有一些不是很干的代码
I have a Some very not DRY code with the GetListOf... Methods
我觉得我应该可以做这样的事情
i feel like i should be able to do something like this
public static List<string> GetListOfProperty(
IEnumerable<Person> listOfPersons, string property)
{
return listOfPersons.Select(x =>x.property).Distinct().OrderBy(x=> x).ToList();
}
但这不是有效的代码.我认为关键可能与创建功能有关
but that is not vaild code. I think the key Might Relate to Creating a Func
如果这就是答案,我该怎么做?
if That is the answer how do I do that?
这是使用反射的第二次尝试,但这也是不行的.
Here is a second attempt using refelection But this is also a no go.
public static List<string> GetListOfProperty(IEnumerable<Person>
listOfPersons, string property)
{
Person person = new Person();
Type t = person.GetType();
PropertyInfo prop = t.GetProperty(property);
return listOfPersons.Select(prop).Distinct().OrderBy(x =>
x).ToList();
}
我认为这可能是死胡同/红鲱鱼,但我想无论如何我都会展示我的作品.
I think the refection might be a DeadEnd/red herring but i thought i would show my work anyway.
请注意,示例代码实际上已简化,用于通过AJAX填充数据列表创建自动完成的体验.该对象具有20多个属性,我可以通过编写20多个方法来完成,但是我觉得应该有一种DRY方式来完成此操作.同样采用这种方法也将清理我的控制器动作.
Note Sample Code is simplified in reality this is used to populate a datalist via AJAX to Create an autocomplete experience. That object has 20+ properties and I can complete by writing 20+ methods but I feel there should be a DRY way to complete this. Also making this one method also would clean up my controller action a bunch also.
问题:
鉴于代码的第一部分,有一种方法可以将这些相似的方法抽象为一个方法,方法是将一些对象传递到select语句中?
Given the first section of code is there a way to abstract those similar methods into a single method buy passing some object into the select Statement???
谢谢您的时间.
推荐答案
您将必须构建选择
.Select(x =>x.property).
用手
.幸运的是,这并不是一个棘手的问题,因为您希望它始终是同一类型(string
),所以:
var x = Expression.Parameter(typeof(Person), "x");
var body = Expression.PropertyOrField(x, property);
var lambda = Expression.Lambda<Func<Person,string>>(body, x);
然后上面的Select
变为:
.Select(lambda).
(对于基于IQueryable<T>
的LINQ)或
(for LINQ based on IQueryable<T>
) or
.Select(lambda.Compile()).
(对于基于IEnumerable<T>
的LINQ).
(for LINQ based on IEnumerable<T>
).
请注意,您可以执行property
来缓存最终表单的任何操作.
Note that anything you can do to cache the final form by property
would be good.
这篇关于LINQ按名称选择属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!