C# LINQ按名称选择属性
我试图在LINQ select语句中使用一个变量 这是我现在正在做的一个例子C# LINQ按名称选择属性,c#,linq,expression,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> l
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();
}
}
}
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用假货;
命名空间控制台测试
{
内部课程计划
{
私有静态void Main(字符串[]args)
{
listOfPersons=新列表
{
新人(),
新人(),
新人(),
新人(),
新人(),
新人(),
新人(),
新人(),
新人(),
新人(),
新人()
};
var firstNames=Person.getListofAffirstnames(listOfPersons);
foreach(人员列表中的变量项)
{
控制台写入线(项目);
}
Console.WriteLine();
Console.ReadKey();
}
公共阶层人士
{
公共字符串City{get;set;}
公共字符串CountryName{get;set;}
公共字符串名{get;set;}
公共字符串LastName{get;set;}
公众人士()
{
FirstName=NameFaker.Name();
LastName=NameFaker.LastName();
City=LocationFaker.City();
CountryName=LocationFaker.Country();
}
公共静态列表GetListofAffirstNames(IEnumerable listOfPersons)
{
返回listOfPersons.Select(x=>x.FirstName).Distinct().OrderBy(x=>x.ToList();
}
公共静态列表GetListOfCities(IEnumerable listOfPersons)
{
返回listOfPersons.Select(x=>x.FirstName).Distinct().OrderBy(x=>x.ToList();
}
公共静态列表GetListOfCountries(IEnumerable listOfPersons)
{
返回listOfPersons.Select(x=>x.FirstName).Distinct().OrderBy(x=>x.ToList();
}
公共静态列表GetListOfLastNames(IEnumerable listOfPersons)
{
返回listOfPersons.Select(x=>x.FirstName).Distinct().OrderBy(x=>x.ToList();
}
}
}
}
我有一些非常不枯燥的代码与GetListOf。。。方法
我觉得我应该可以做这样的事情
public static List<string> GetListOfProperty(
IEnumerable<Person> listOfPersons, string property)
{
return listOfPersons.Select(x =>x.property).Distinct().OrderBy(x=> x).ToList();
}
公共静态列表GetListOfProperty(
IEnumerable listOfPersons,字符串属性)
{
返回listOfPersons.Select(x=>x.property).Distinct().OrderBy(x=>x.ToList();
}
但这不是有效的代码。我认为关键可能与创建Func有关
如果这是答案,我该怎么做
这里是使用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();
}
公共静态列表GetListOfProperty(IEnumerable)
listOfPersons,字符串属性)
{
Person=新人();
类型t=person.GetType();
PropertyInfo prop=t.GetProperty(属性);
返回listOfPersons.Select(prop).Distinct().OrderBy(x=>
x) .ToList();
}
我认为反思可能是一个死胡同/红鲱鱼,但我认为我无论如何都会展示我的工作
注意:示例代码在现实中被简化了,这是用来通过AJAX填充来创建自动完成体验的。这个对象有20多个属性,我可以通过编写20多个方法来完成,但我觉得应该有一个干涸的方法来完成。同样,使用这个方法也会清理我的控制器动作
问题:
给定代码的第一部分,有没有办法将这些类似的方法抽象为一个方法,并将一些对象传递到select语句中
谢谢您的时间。您必须构建select
.Select(x =>x.property).
用手。幸运的是,这不是一个棘手的问题,因为您希望它始终是相同的类型(string
),因此:
(对于基于IQueryable
的LINQ)或
(对于基于IEnumerable
的LINQ)
请注意,您可以通过
属性来缓存最终表单。从您的示例中,我认为您需要的是:
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();
你应该能够通过反思来做到这一点。我用的是类似的东西
只需更改您的反射,尝试以下操作:
public static List<string> GetListOfValues(IEnumerable<Person> listOfPersons, string propertyName)
{
var ret = new List<string>();
PropertyInfo prop = typeof(Person).GetProperty(propertyName);
if (prop != null)
ret = listOfPersons.Select(p => prop.GetValue(p).ToString()).Distinct().OrderBy(x => x).ToList();
return ret;
}
公共静态列表GetListOfValues(IEnumerable listOfPersons,string propertyName)
{
var ret=新列表();
PropertyInfo prop=typeof(Person).GetProperty(propertyName);
如果(prop!=null)
ret=listOfPersons.Select(p=>prop.GetValue(p.ToString()).Distinct().OrderBy(x=>x.ToList();
返回ret;
}
我希望有帮助
它是基于C#6的
我会尽可能远离反射和硬编码字符串
如何定义一个接受函数选择器T的扩展方法,以便您可以处理字符串属性之外的其他类型
public static List<T> Query<T>(this IEnumerable<Person> instance, Func<Person, T> selector)
{
return instance
.Select(selector)
.Distinct()
.OrderBy(x => x)
.ToList();
}
您只需使用类型安全的lambda选择器获取结果
var ids = listOfPersons.Query(p => p.Id);
var firstNames = listOfPersons.Query(p => p.FirstName);
var lastNames = listOfPersons.Query(p => p.LastName);
var cityNames = listOfPersons.Query(p => p.City);
var countryNames = listOfPersons.Query(p => p.CountryName);
编辑
由于您似乎真的需要硬编码字符串作为属性输入,那么省略一些动态性并使用一点确定性如何
public static List<string> Query(this IEnumerable<Person> instance, string property)
{
switch (property)
{
case "ids": return instance.Query(p => p.Id.ToString());
case "firstName": return instance.Query(p => p.FirstName);
case "lastName": return instance.Query(p => p.LastName);
case "countryName": return instance.Query(p => p.CountryName);
case "cityName": return instance.Query(p => p.City);
default: throw new Exception($"{property} is not supported");
}
}
你也可以用这个。对我有用
public static class ObjectReflectionExtensions
{
public static object GetValueByName<T>(this T thisObject, string propertyName)
{
PropertyInfo prop = typeof(T).GetProperty(propertyName);
return prop.GetValue(thisObject);
}
}
公共静态类ObjectReflectionExtensions
{
公共静态对象GetValueByName(此对象为thisObject,字符串propertyName)
{
PropertyInfo prop=typeof(T).GetProperty(propertyName);
返回prop.GetValue(thisObject);
}
}
像这样打电话
public static List<string> GetListOfProperty(IEnumerable<Person> listOfPersons, string propertyName)
{
return listOfPersons.Select(x =>(string)x.GetValueByName(propertyName)).Distinct().OrderBy(x=> x).ToList();
}
公共静态列表GetListOfProperty(IEnumerable listOfPersons,string propertyName)
{
返回listOfPersons.Select(x=>(string)x.GetValueByName(propertyName)).Distinct().OrderBy(x=>x.ToList();
}
如果要选择所有值:
object[] foos = objects.Select(o => o.GetType().GetProperty("PropertyName").GetValue(o)).ToArray();
除了显示调用GetProperty()的代码?DV以及在没有阅读MSDN文档的情况下到这里寻求帮助的代码之外,您还可以用文字说明您的问题吗。您的答案在文档中。@Crowcoder这只是另一个想要选择属性的人
var ids = listOfPersons.Query(p => p.Id);
var firstNames = listOfPersons.Query(p => p.FirstName);
var lastNames = listOfPersons.Query(p => p.LastName);
var cityNames = listOfPersons.Query(p => p.City);
var countryNames = listOfPersons.Query(p => p.CountryName);
public static List<string> Query(this IEnumerable<Person> instance, string property)
{
switch (property)
{
case "ids": return instance.Query(p => p.Id.ToString());
case "firstName": return instance.Query(p => p.FirstName);
case "lastName": return instance.Query(p => p.LastName);
case "countryName": return instance.Query(p => p.CountryName);
case "cityName": return instance.Query(p => p.City);
default: throw new Exception($"{property} is not supported");
}
}
var cityNames = listOfPersons.Query("cityName");
public static class ObjectReflectionExtensions
{
public static object GetValueByName<T>(this T thisObject, string propertyName)
{
PropertyInfo prop = typeof(T).GetProperty(propertyName);
return prop.GetValue(thisObject);
}
}
public static List<string> GetListOfProperty(IEnumerable<Person> listOfPersons, string propertyName)
{
return listOfPersons.Select(x =>(string)x.GetValueByName(propertyName)).Distinct().OrderBy(x=> x).ToList();
}
object[] foos = objects.Select(o => o.GetType().GetProperty("PropertyName").GetValue(o)).ToArray();