匿名类型的属性列表
本文关键字:属性 列表 类型 | 更新日期: 2023-09-27 18:35:47
假设我有某种类型:
public class General
{
public int Id;
public string Name;
public DateTime modified
}
假设我想要一些函数过滤器匿名:
public void DoWorkOnSubset(List<General> generals, params Func<general, object> properties)
{
}
如何获取属性列表并将其转换为匿名类型
generals.Select(x => new { properties.ForEach( p => p.Invoke(x)) });
不能在运行时生成新的匿名类型,因为匿名类型是实际类型,由后台的编译器生成。.NET 用户无法通过 API 使用生成这些类型的代码,因此必须通过System.Reflection.Emit
调用才能生成自己的类型。
下一个最接近的事情是使用动态对象,例如 ExpandoObject
,并使用 IDictionary<string,object>
接口设置其值。调用方将能够使用常规语法访问此对象的字段。
编辑:如果您所需要的只是可以在运行时访问的属性值集合,则可以使用 Dictionary<string,object>
,如下所示:
generals.Select(x =>
properties.ToDictionary(p => p.Name, p => p.Invoke(x))
);
如果有人想知道,我想出了一种无需匿名类型即可实现此目的的方法。 我只有一个 IE无数的属性。
generals.Select(x => properties.Select(p => p.Invoke(x)));
我可以将其作为 IEnumerable 而不是匿名类型进行操作
我有相同的解决方案,并通过一个简单的类并从中继承我的所有实体来解决这个问题:
public class Entity
{
public Entity()
{
EntityPropertyDic = new Dictionary<string, object>();
}
public object this[string propertyName]
{
get
{
if (EntityPropertyDic.ContainsKey(propertyName))
{
return EntityPropertyDic[propertyName];
}
else
throw new ArgumentException("PropertyName Is not exist!");
}
set
{
OnColumnChanging(propertyName, ref value);
EntityPropertyDic[propertyName] = value;
}
}
private void OnColumnChanging(string propertyName, ref object value)
{
throw new NotImplementedException();
}
protected Dictionary<string, object> EntityPropertyDic { get; set; }
}
所以你可以这样做:
public List<Entity> DoWorkOnSubset(List<General> generals, params string properties)
{
List<Entity> entityList = new List<Entity>();
foreach(var general in generals)
{
var entity = new Entity();
foreach(var prop in properties)
{
entity[prop] = general[prop];
}
entityList.Add(entity);
}
return entityList;
}