【问题标题】:C# Determine the type of a generic listC#确定泛型列表的类型
【发布时间】:2013-07-11 22:07:07
【问题描述】:

我有一个需要向其中传递各种列表的 C# 方法。列表的类型经常会有所不同。方法本身在不同的 dll 中,无法知道列表中包含的类对象(没有引用,没有 using 语句)。该方法需要读取列表中每个项目的每个成员,并在此基础上构建并返回一个字符串。

我的问题是如何在编译时/运行时获取这些不同对象的元数据?反射会这样做吗?

另外,一旦我得到元数据,我如何使用它来实际使用变量?

谢谢

编辑:目前我正在使用它,如下所示:

public string GetData(List<User> list){
//...
    List<RowData> rows = new List<RowData>();
    foreach (User item in list)
    {
        RowData row = new RowData();
        row.id = count++;
        row.cell = new string[3];
        row.cell[0] = item.ID.ToString();
        row.cell[1] = item.name;
        row.cell[2] = item.age.ToString();

        rows.Add(row);
     }
//...
    return new JavaScriptSerializer().Serialize(rows.ToArray());

现在这是非常具体的。我想用泛型替换它,这样我就可以传递“用户”以外的项目

【问题讨论】:

  • 反射是你想要的,是的。有关一些好的介绍性链接,请参阅此答案:stackoverflow.com/questions/9428779/…
  • 或许也可以考虑使用dynamic,以避免直接通过反射跳过箍。
  • 我已经更新了这个问题,详细说明了使用情况
  • @Mike 再次检查我的答案

标签: c# list reflection


【解决方案1】:

如果进入该方法的参数(将其称为list 以供讨论)是List&lt;T&gt;,那么您可以执行以下操作:

Type type = list.GetType().GetGenericArguments()[0];

如果您只有一个通用的 T 类,那么您可以随时使用:

Type typeParameterType = typeof(T);

【讨论】:

  • 你需要小心一点;我可以创建一个class Foo : List&lt;User&gt;,并将Foo 传递给该方法——它可以工作,但GetGenericArguments() 调用会失败
【解决方案2】:

.GetType() 会给你一个Type,你可以得到很多关于这个类型的描述。

您还可以使用反射发现实例的成员

请更准确地说出你想要什么?

编辑:这是一种方法,尝试使其成为扩展方法会更好

public static List<RowData> ToDataTable<T>(IEnumerable<T> source)
{
    System.Reflection.PropertyInfo[] properties = typeof(T).GetProperties();
    List<RowData> rows = new List<JQGridRow>();


    foreach (var item in source)
    {
        RowData row = new RowData();
        row.cells = new string[properties.Length];
        int i=0;
        foreach (var prop in properties)
        {  
             row.cells[i] = prop.GetValue(item, null);i++;
        }
       rows.Add(row);
    }
    return rows;
}

【讨论】:

  • 谢谢,这很有效(有一些小的语法调整)。
【解决方案3】:

是的,您可以在运行时使用反射来获取对象的类型。

object.GetType() 的简单调用将为您提供此实例的类型。

您如何处理这些信息取决于您。

【讨论】:

    【解决方案4】:

    也许是这样的?

        public string GetData<T>(IEnumerable<T> list, Func<T, RowData> fillRow)
        {
            List<RowData> rows = new List<JQGridRow>();
            foreach (User item in list)
            {
                RowData row = new RowData();
                row.id = count++;
    
                fillRow(row);
    
                rows.Add(row);
            }
            //...
            return new JavaScriptSerializer().Serialize(rows.ToArray());
        }
    

    并像使用它

            string s = GetData(users, row =>
            {
                row.cell = new string[3];
                row.cell[0] = item.ID.ToString();
                row.cell[1] = item.name;
                row.cell[2] = item.age.ToString();
            });
    

    【讨论】:

      【解决方案5】:

      如果您将它们全部视为对象,使用内部的 ToString() 方法构建字符串,这可能会起作用。

      【讨论】:

        猜你喜欢
        • 2011-02-24
        • 1970-01-01
        • 1970-01-01
        • 2010-12-06
        • 1970-01-01
        • 1970-01-01
        • 2023-03-26
        • 1970-01-01
        相关资源
        最近更新 更多