How to get the type of T from a member of a generi

2018-12-31 05:55发布

Let say I have a generic member in a class or method, so:

public class Foo<T>
{
    public List<T> Bar { get; set; }

    public void Baz()
    {
        // get type of T
    }   
}

When I instantiate the class, the T becomes MyTypeObject1, so the class has a generic list property: List<MyTypeObject1>. The same applies to a generic method in a non-generic class:

public class Foo
{
    public void Bar<T>()
    {
        var baz = new List<T>();

        // get type of T
    }
}

I would like to know, what type of objects the list of my class contains. So the list property called Bar or the local variable baz, contains what type of T?

I cannot do Bar[0].GetType(), because the list might contain zero elements. How can I do it?

标签: c# .net generics
16条回答
明月照影归
2楼-- · 2018-12-31 06:50

I use this extension method to accomplish something similar:

public static string GetFriendlyTypeName(this Type t)
{
    var typeName = t.Name.StripStartingWith("`");
    var genericArgs = t.GetGenericArguments();
    if (genericArgs.Length > 0)
    {
        typeName += "<";
        foreach (var genericArg in genericArgs)
        {
            typeName += genericArg.GetFriendlyTypeName() + ", ";
        }
        typeName = typeName.TrimEnd(',', ' ') + ">";
    }
    return typeName;
}

You use it like this:

[TestMethod]
public void GetFriendlyTypeName_ShouldHandleReallyComplexTypes()
{
    typeof(Dictionary<string, Dictionary<string, object>>).GetFriendlyTypeName()
        .ShouldEqual("Dictionary<String, Dictionary<String, Object>>");
}

This isn't quite what you're looking for, but it's helpful in demonstrating the techniques involved.

查看更多
荒废的爱情
3楼-- · 2018-12-31 06:51

If you dont need the whole Type variable and just want to check the type you can easily create a temp variable and use is operator.

T checkType = default(T);

if (checkType is MyClass)
{}
查看更多
查无此人
4楼-- · 2018-12-31 06:52

Consider this: I use it to export 20 typed list by same way:

private void Generate<T>()
{
    T item = (T)Activator.CreateInstance(typeof(T));

    ((T)item as DemomigrItemList).Initialize();

    Type type = ((T)item as DemomigrItemList).AsEnumerable().FirstOrDefault().GetType();
    if (type == null) return;
    if (type != typeof(account)) //account is listitem in List<account>
    {
        ((T)item as DemomigrItemList).CreateCSV(type);
    }
}
查看更多
流年柔荑漫光年
5楼-- · 2018-12-31 06:52

If you want to know a property's underlying type, try this:

propInfo.PropertyType.UnderlyingSystemType.GenericTypeArguments[0]
查看更多
登录 后发表回答