C# 如何确定泛型列表的类型

3
我有一个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());

目前这很具体化。我希望使用泛型来替换它,以便我可以传递除“用户”之外的其他项。


反射是你想要的,没错。请参考这个答案中提供的一些好的入门链接:https://dev59.com/PWox5IYBdhLWcg3wHAsA - Katie Kilian
也许考虑使用 dynamic,以避免直接使用反射跳过障碍。 - Chris Sinclair
我已经更新了问题,并提供了有关使用的具体信息。 - Mike
@Mike 请再次检查我的答案。 - sm_
5个回答

5

如果方法传入的参数(假设我们称之为list)是List<T>类型,你可以这样做:

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

如果您只有一个通用的T类,那么您可以始终使用以下方法:
Type typeParameterType = typeof(T);

1
你需要小心一点;我可以创建一个 class Foo : List<User>,并将一个 Foo 传递到该方法中 - 这样做是可行的,但 GetGenericArguments() 调用会失败。 - Marc Gravell

3

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

1
谢谢,这个成功了(只需要进行一些小的语法调整)。 - Mike

1
也许是这样的吗?
    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();
        });

1

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

只需简单调用object.GetType()即可获取此实例的类型。

您可以根据这些信息进行任何操作。


0

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接