匿名类型的属性列表

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;
}