匿名类型的属性列表
List of properties to anonymous Type
假设我有一些类型:
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))
);
如果有人想知道我想出了一种无需匿名类型即可实现此目的的方法。我只有一个 IEnumerable 属性。
generals.Select(x => properties.Select(p => p.Invoke(x)));
我可以将其作为 IEnumerable 而不是匿名类型来操作
我有相同的解决方案,并通过简单的 class 解决了这个问题,并从中继承了我的所有实体:
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;
}
假设我有一些类型:
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))
);
如果有人想知道我想出了一种无需匿名类型即可实现此目的的方法。我只有一个 IEnumerable 属性。
generals.Select(x => properties.Select(p => p.Invoke(x)));
我可以将其作为 IEnumerable 而不是匿名类型来操作
我有相同的解决方案,并通过简单的 class 解决了这个问题,并从中继承了我的所有实体:
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;
}