140

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

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

4 に答える 4

258
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;
    }
}
于 2009-06-25T13:02:32.773 に答える
23

ある種のオブジェクトであると思われる場合、それが何であるかをどのIList<>ように判断できますか?IList<>

これが根性のある解決策です。これは、(ではなくType)テストする実際のオブジェクトがあることを前提としています。

public static Type ListOfWhat(Object list)
{
    return ListOfWhat2((dynamic)list);
}

private static Type ListOfWhat2<T>(IList<T> list)
{
    return typeof(T);
}

使用例:

object value = new ObservableCollection<DateTime>();
ListOfWhat(value).Dump();

プリント

typeof(DateTime)
于 2012-11-28T15:33:22.640 に答える
12

マークの答えは私がこれに使用するアプローチですが、簡単にするために(そしてより親しみやすいAPI?)、次のようなものがある場合はコレクション基本クラスでプロパティを定義できます。

public abstract class CollectionBase<T> : IList<T>
{
   ...

   public Type ElementType
   {
      get
      {
         return typeof(T);
      }
   }
}

私はこのアプローチが有用であり、ジェネリック医薬品の初心者にとっては理解しやすいと感じました。

于 2009-06-25T13:52:29.070 に答える
9

ある種のオブジェクトであると思われる場合、それが何であるかをどのIList<>ように判断できますか?IList<>

これが信頼できる解決策です。長さについてお詫びします-C#のイントロスペクションAPIにより、これは驚くほど困難になります。

/// <summary>
/// Test if a type implements IList of T, and if so, determine T.
/// </summary>
public static bool TryListOfWhat(Type type, out Type innerType)
{
    Contract.Requires(type != null);

    var interfaceTest = new Func<Type, Type>(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IList<>) ? i.GetGenericArguments().Single() : null);

    innerType = interfaceTest(type);
    if (innerType != null)
    {
        return true;
    }

    foreach (var i in type.GetInterfaces())
    {
        innerType = interfaceTest(i);
        if (innerType != null)
        {
            return true;
        }
    }

    return false;
}

使用例:

    object value = new ObservableCollection<int>();
Type innerType;
TryListOfWhat(value.GetType(), out innerType).Dump();
innerType.Dump();

戻り値

True
typeof(Int32)
于 2012-11-28T15:20:36.770 に答える