Wiz*_*mer 6 c# linq expression
我试图在LINQ select语句中使用变量.
这是我现在正在做的一个例子.
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();
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
我有一些非常不干的代码与GetListOf ...方法
我觉得我应该可以做这样的事情
public static List<string> GetListOfProperty(
IEnumerable<Person> listOfPersons, string property)
{
return listOfPersons.Select(x =>x.property).Distinct().OrderBy(x=> x).ToList();
}
Run Code Online (Sandbox Code Playgroud)
但这不是虚拟代码.我认为关键在于创造一个功能
如果这就是答案我该怎么做?
这是使用refelection的第二次尝试但是这也是不行的.
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();
}
Run Code Online (Sandbox Code Playgroud)
我认为反射可能是一个DeadEnd /红鲱鱼,但我想我还是会展示我的作品.
注意实际上简化了示例代码,它用于通过AJAX 填充数据列表以创建自动完成体验.该对象具有20多个属性,我可以通过编写20多种方法来完成,但我觉得应该有一种干燥的方法来完成它.同样制作这个方法也会清理我的控制器动作.
题:
鉴于代码的第一部分有一种方法将这些类似的方法抽象为单个方法,请将一些对象传递给select语句???
感谢您的时间.
从你的例子来看,我认为你想要的是这样的:
public static List<string> GetListOfProperty(IEnumerable<Person>
listOfPersons, string property)
{
Type t = typeof(Person);
PropertyInfo prop = t.GetProperty(property);
return listOfPersons
.Select(person => (string)prop.GetValue(person))
.Distinct()
.OrderBy(x => x)
.ToList();
Run Code Online (Sandbox Code Playgroud)
}
typeof是 C# 中的内置运算符,您可以将类型名称“传递”给它,它将返回相应的实例Type。它在编译时而不是运行时工作,因此它不像普通函数那样工作。
PropertyInfo有一个GetValue采用对象参数的方法。对象是要从中获取属性值的类型的实例。如果您尝试定位某个static属性,请使用null该参数。
GetValue返回一个object,您必须将其转换为实际类型。
person => (string)prop.GetValue(person)是一个lambda表达式,其签名如下:
string Foo(Person person) { ... }
如果您希望它适用于任何类型的属性,请将其设为通用而不是硬编码string。
public static List<T> GetListOfProperty<T>(IEnumerable<Person>
listOfPersons, string property)
{
Type t = typeof(Person);
PropertyInfo prop = t.GetProperty(property);
return listOfPersons
.Select(person => (T)prop.GetValue(person))
.Distinct()
.OrderBy(x => x)
.ToList();
}
Run Code Online (Sandbox Code Playgroud)
您将必须建立选择
.Select(x =>x.property).
Run Code Online (Sandbox Code Playgroud)
用手。幸运的是,这并不是一个棘手的问题,因为您希望它始终是同一类型(string),因此:
var x = Expression.Parameter(typeof(Person), "x");
var body = Expression.PropertyOrField(x, property);
var lambda = Expression.Lambda<Func<Person,string>>(body, x);
Run Code Online (Sandbox Code Playgroud)
然后Select上面变成:
.Select(lambda).
Run Code Online (Sandbox Code Playgroud)
(基于的LINQ IQueryable<T>)或
.Select(lambda.Compile()).
Run Code Online (Sandbox Code Playgroud)
(基于的LINQ IEnumerable<T>)。
请注意,您可以采取任何措施来缓存最终表单property。
| 归档时间: |
|
| 查看次数: |
5660 次 |
| 最近记录: |