1. ホーム
  2. c#

[解決済み] C# generic list <T> Tの型を取得する方法は?重複

2022-05-27 01:33:55

質問

リフレクションのプロジェクトに取り組んでいるのですが、今、行き詰っています。

のオブジェクトがある場合 myclass を保持することができ List<SomeClass> を保持することができる場合、以下のコードのようにタイプを取得する方法を知っている人はいますか? myclass.SomList が空である場合、以下のコードのように型を取得する方法を知っている人はいますか?

List<myclass> myList = dataGenerator.getMyClasses();
lbxObjects.ItemsSource = myList; 
lbxObjects.SelectionChanged += lbxObjects_SelectionChanged;

private void lbxObjects_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    Reflect();
}

Private void Reflect()
{
    foreach (PropertyInfo pi in lbxObjects.SelectedItem.GetType().GetProperties())
    {
        switch (pi.PropertyType.Name.ToLower())
        {
            case "list`1":
            {           
                // This works if the List<T> contains one or more elements.
                Type tTemp = GetGenericType(pi.GetValue(lbxObjects.SelectedItem, null));

                // but how is it possible to get the Type if the value is null? 
                // I need to be able to create a new object of the type the generic list expect. 
                // Type type = pi.getType?? // how to get the Type of the class inside List<T>?
                break;
            }
        }
    }
}

private Type GetGenericType(object obj)
{
    if (obj != null)
    {
        Type t = obj.GetType();
        if (t.IsGenericType)
        {
            Type[] at = t.GetGenericArguments();
            t = at.First<Type>();
        } 
        return t;
    }
    else
    {
        return null;
    }
}

どのように解決するのですか?

Type type = pi.PropertyType;
if(type.IsGenericType && type.GetGenericTypeDefinition()
        == typeof(List<>))
{
    Type itemType = type.GetGenericArguments()[0]; // use this...
}


より一般的には、あらゆる IList<T> をサポートするには、インターフェイスを確認する必要があります。

foreach (Type interfaceType in type.GetInterfaces())
{
    if (interfaceType.IsGenericType &&
        interfaceType.GetGenericTypeDefinition()
        == typeof(IList<>))
    {
        Type itemType = type.GetGenericArguments()[0];
        // do something...
        break;
    }
}