c# - 如何根据作为字符串数组发送的属性名称从通用列表中提取特定属性?

标签 c# asp.net .net asp.net-mvc generics

我有一个类型为 List<InstanceDataLog> 的通用列表其中有大量的属性。我想将一些属性的名称传递给一个方法,并想从此列表中提取一个经过优化的列表。

public void Export(string col)   //a,b,c
{
    string [] selectedcol = col.Split(',');
    var grid = new GridView();
    var data = TempData["InstanceDataList"];
    List<InstanceDataLog> lst = new List<InstanceDataLog>();
    List<EToolsViewer.APIModels.InstanceDataLog> lstrefined = new List<InstanceDataLog>();
    lst=   (List<EToolsViewer.APIModels.InstanceDataLog>)TempData["InstanceDataList"];

     var r= lst.Select(e => new {e.a, e.b}).ToList();// I would like to replace these hardcoded properties with names of properties present in `selectedcol `

    grid.DataSource =r;
    grid.DataBind();
}

为了进一步澄清,假设InstanceDataLog有 5 个属性:a、b、c、d、e 我想传递 a、b 并能够提取只有属性 a、b 的新列表

编辑:

 $('#export').mousedown(function () {

 window.location = '@Url.Action("Export", "TrendsData",new { col = "a,b,c" })';

});

最佳答案

你可以使用这样的方法来获取属性:

private object getProperty(EToolsViewer.APIModels.InstanceDataLog e, string propName)
    {
 var propInfo =typeof(EToolsViewer.APIModels.InstanceDataLog).GetProperty(propName);
    return propInfo.GetValue(e);        
}

通过另一个函数你可以获得你想要的所有属性:

private dynamic getProperties(string[] props, EToolsViewer.APIModels.InstanceDataLog e )
{
    var ret = new ExpandoObject() as IDictionary<string, Object>;;
    foreach (var p in props)
    {
        ret.Add(p, getProperty(e, p));
    }       
    return ret;
}

如果您尝试将 DataSource 分配给 expando 对象,则会出现此问题。解决方案描述如下:

Binding a GridView to a Dynamic or ExpandoObject object

我们确实需要另一种方法:

public DataTable ToDataTable(IEnumerable<dynamic> items)
{
    var data = items.ToArray();
    if (data.Count() == 0) return null;

    var dt = new DataTable();
    foreach (var key in ((IDictionary<string, object>)data[0]).Keys)
    {
        dt.Columns.Add(key);
    }
    foreach (var d in data)
    {
        dt.Rows.Add(((IDictionary<string, object>)d).Values.ToArray());
    }
    return dt;
}

并使用它:

var r = lst.Select(e => getProperties(selectedcol, e)).ToList();
grid.DataSource = ToDataTable(r);

同样的事情,但准备好为 LinqPad 运行:

void Main()
{
    var samples = new[] { new Sample { A = "A", B = "B", C = "C" }, new Sample { A = "A1", B = "B2", C = "C1" } };
    var r = samples.Select(e => getProperties(new[] {"A", "C", "B"}, e)).ToList();
    r.Dump();
}

private object getProperty(Sample e, string propName)
{
    var propInfo = typeof(Sample).GetProperty(propName);
    return propInfo.GetValue(e);
}

private dynamic getProperties(string[] props, Sample e)
{
    var ret = new ExpandoObject() as IDictionary<string, Object>; ;
    foreach (var p in props)
    {
        ret.Add(p, getProperty(e, p));
    }
    return ret;
}

public class Sample
{
    public string A { get; set;}
    public string B { get; set;}
    public string C { get; set;}
}

输出:

enter image description here

关于c# - 如何根据作为字符串数组发送的属性名称从通用列表中提取特定属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40863405/

相关文章:

c# - 无一异常(exception)地设置属性时单例类崩溃

c# - 创意模式建议

c# - WCF 跟踪代码

asp.net - jQuery 并在回调中解析 JSON

.net - 使用 javascript 解密数据 - ASP.NET 网站

c# - 如何在文件的一部分上使用 DeflateStream?

c# - 接口(interface)优化代码?

c# - 从源文件中删除所有注释(单行/多行)和空行

C# 服务器-客户端应用程序建议

css - 如何在 ASP.NET Web 窗体中渲染 CSS 内联