当前位置:  开发笔记 > 编程语言 > 正文

如何从泛型类或方法的成员中获取T的类型?

如何解决《如何从泛型类或方法的成员中获取T的类型?》经验,为你挑选了11个好方法。

假设我在类或方法中有一个泛型成员,所以:

public class Foo
{
    public List Bar { get; set; }

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

当我实例化类时,T变为MyTypeObject1,所以类具有通用列表属性:List.这同样适用于非泛型类中的泛型方法:

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

        // get type of T
    }
}

我想知道,我的类列表包含什么类型的对象.所以调用的list属性Bar或局部变量baz包含什么类型的T

我做不到Bar[0].GetType(),因为列表可能包含零元素.我该怎么做?



1> Tamas Czineg..:

如果我理解正确,您的列表与容器类本身具有相同的类型参数.如果是这种情况,那么:

Type typeParameterType = typeof(T);

如果您处于object作为类型参数的幸运情况,请参阅Marc的答案.


我喜欢`typeof`的可读性.如果你想知道T的类型,只需使用`typeof(T)`:)
哈哈 - 是的,非常真实; 我认为OP只有`object`,`IList`或类似的东西 - 但这很可能是正确的答案.
我实际上只是使用了typeof(Type)而且效果很好.

2> Marc Gravell..:

(注:我假设你知道objectIList或类似的,并且这个名单可以是任何类型的在运行时)

如果你知道它是a List,那么:

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

另一种选择是查看索引器:

Type type = abc.GetType().GetProperty("Item").PropertyType;

使用新的TypeInfo:

using System.Reflection;
// ...
var type = abc.GetType().GetTypeInfo().GenericTypeArguments[0];


@Daok:那么它不是List
任何具有一种类型参数的通用都应该有效.

3> 3dGrabber..:

使用以下扩展方法,您可以在没有反射的情况下逃脱:

public static Type GetListType(this List _)
{
    return typeof(T);
}

或者更一般:

public static Type GetEnumeratedType(this IEnumerable _)
{
    return typeof(T);
}

用法:

List        list    = new List { "a", "b", "c" };
IEnumerable strings = list;
IEnumerable objects = list;

Type listType    = list.GetListType();           // string
Type stringsType = strings.GetEnumeratedType();  // string
Type objectsType = objects.GetEnumeratedType();  // BEWARE: object


这只有在编译时已经知道`T`的类型时才有用.在这种情况下,您根本不需要任何代码.

4> Rauhotz..:

尝试

list.GetType().GetGenericArguments()


new List ().GetType().GetGenericArguments()返回System.Type [1],其中System.Int32为条目

5> 小智..:

这对我有用.myList是一些未知的列表.

IEnumerable myEnum = myList as IEnumerable;
Type entryType = myEnum.AsQueryable().ElementType;



6> Sebi..:

如果您不需要整个Type变量并且只想检查类型,则可以轻松创建临时变量并使用is运算符.

T checkType = default(T);

if (checkType is MyClass)
{}



7> 小智..:

您可以将此一个用于通用列表的返回类型:

public string ListType(T value)
{
    var valueType = value.GetType().GenericTypeArguments[0].FullName;
    return valueType;
}



8> 小智..:

考虑一下:我使用它以相同的方式导出20个类型列表:

private void Generate()
{
    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
    {
        ((T)item as DemomigrItemList).CreateCSV(type);
    }
}



9> 小智..:

GetGenericArgument()必须在实例的基本类型(其类是泛型类myClass)上设置该方法.否则,它返回一个类型[0]

例:

Myclass instance = new Myclass();
Type[] listTypes = typeof(instance).BaseType.GetGenericArguments();



10> Dan Malcolm..:

您可以使用以下方法从实现IEnumerable 的任何集合类型中获取“ T”类型:

public static Type GetCollectionItemType(Type collectionType)
{
    var types = collectionType.GetInterfaces()
        .Where(x => x.IsGenericType 
            && x.GetGenericTypeDefinition() == typeof(IEnumerable<>))
        .ToArray();
    // Only support collections that implement IEnumerable once.
    return types.Length == 1 ? types[0].GetGenericArguments()[0] : null;
}

请注意,它不支持两次实现IEnumerable 的集合类型,例如

public class WierdCustomType : IEnumerable, IEnumerable { ... }

我想如果您需要支持此类型,则可以返回一个类型数组。

另外,如果您经常这样做(例如循环执行),则可能还希望按集合类型缓存结果。



11> Ken Smith..:

我使用此扩展方法来完成类似的操作:

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

public static string StripStartingWith(this string s, string stripAfter)
{
    if (s == null)
    {
        return null;
    }
    var indexOf = s.IndexOf(stripAfter, StringComparison.Ordinal);
    if (indexOf > -1)
    {
        return s.Substring(0, indexOf);
    }
    return s;
}

您可以这样使用它:

[TestMethod]
public void GetFriendlyTypeName_ShouldHandleReallyComplexTypes()
{
    typeof(Dictionary>).GetFriendlyTypeName()
        .ShouldEqual("Dictionary>");
}

这并不是您要找的东西,但是对演示所涉及的技术很有帮助。

推荐阅读
360691894_8a5c48
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有