匿名类型的属性列表

本文关键字:属性 列表 类型 | 更新日期: 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;
}