说我有一些类型:
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)) });
答案 0 :(得分:2)
您无法在运行时生成新的匿名类型,因为匿名类型是由场景后面的编译器生成的实际类型。 .NET用户无法通过API使用生成这些类型的代码,因此您必须通过System.Reflection.Emit
调用来构建自己的代码。
下一个最接近的事情是使用动态对象,例如ExpandoObject
,并使用IDictionary<string,object>
接口设置其值。调用者可以使用常规语法访问该对象的字段。
编辑:如果你需要的只是一个可以在运行时访问的方式的属性值集合,你可以使用Dictionary<string,object>
,如下所示:
generals.Select(x =>
properties.ToDictionary(p => p.Name, p => p.Invoke(x))
);
答案 1 :(得分:1)
如果有人想知道我找到了一种方法来实现这一点,而不是匿名类型。我只是拥有一个IEnumerable属性。
generals.Select(x => properties.Select(p => p.Invoke(x)));
我可以将其作为IEnumerable而不是匿名类型
进行操作答案 2 :(得分:1)
我有相同的解决方案并通过一个简单的类解决它并继承我的所有实体:
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;
}