【问题标题】:How to select from the list only some properties depending from list of property names?如何根据属性名称列表仅从列表中选择一些属性?
【发布时间】:2020-10-30 23:25:51
【问题描述】:

我正在寻找结果是匿名但属性是从字符串列表中给出的选择

例子

public class A{
     public string PropertyA {get; set;}
     public double PropertyB {get; set;}
     public double PropertyC {get; set;}
     public double PropertyD {get; set;}
}

var list = new List<A>{ ... };

var propertyNames = new List<string>{"PropertyA", "PropertyD"}

我想创建一个 选择器,它使用 PropertyA 和 PropertyD 创建一个匿名的,所以我可以得到类似的东西

var result = list.Select( selector(propertynames) ).ToList();

其中 result[0] 又是匿名的,具有诸如 result[0].PropertyA 和 result[0].PropertyD 之类的属性

【问题讨论】:

  • @TheGeneral 我实际上需要的是序列化最终列表并作为查询结果传递。想象一下它是数据库中 sql 选择的结果...

标签: c# linq .net-core system.reflection


【解决方案1】:

我真的,真的建议对此采取不同的做法。
但是,这是解决此问题的一种方法 - 使用 System.Dynamic.ExpandoObject

var result = list
    .Select(i =>
    {
        var expando = new ExpandoObject();
        var expandoAsDict = (IDictionary<string, object>)expando;
        var targetProperties = i
            .GetType()
            .GetProperties()
            .Where(p => propertyNames.Contains(p.Name))
            .ToDictionary(p => p.Name, p => p.GetValue(i));
        foreach (var property in targetProperties)
        {
            expandoAsDict.Add(property);
        }
        return (dynamic)expando;
    })
    .ToList();

然后您可以按照您的描述进行操作,例如:

Console.WriteLine(result[0].PropertyA);

写出期望值。

当然,您可以忘记对动态类型的 Intellisense 支持(如果一开始并不明显)。
注意:另一种方法是在运行时使用System.Reflection.Emit 构造您的类型,但这会更尴尬。

祝你好运!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-05
    • 1970-01-01
    • 1970-01-01
    • 2018-05-26
    • 2017-08-20
    相关资源
    最近更新 更多