1

方法があります

T Get<T>(string key)
{..
}

発信者が私に電話をかけてきたら、次のT = IEnumerable<V>ことを行う必要があります。

return GetEnum<V>(key)

したがって、私はする必要があります

  • T がIEnumerable<X>
  • X を取得し、それを GetEnum メソッドに押し込みます

私は2番目のものを行うことができないと思います

もちろん、別のメソッドを書くこともできますが、それは既存のコード ベースとの契約ではありません。

4

1 に答える 1

2

あなたは少しの反省でそれをすることができます、しかしそれは特に速くはありません:

static class TheClass
{
   public static T Get<T>(string key)
   {
      // Adjust these as required:
      const BindingFlags flags = BindingFlags.Static | BindingFlags.NonPublic;

      if (typeof(T).IsGenericType && typeof(IEnumerable<>) == typeof(T).GetGenericTypeDefinition())
      {
         Type v = typeof(T).GetGenericArguments()[0];
         var baseMethod = typeof(TheClass).GetMethod("GetEnum", flags);
         var realMethod = baseMethod.MakeGenericMethod(v);
         return (T)(object)realMethod.Invoke(null, new[] { key });
      }

      // TODO: Handle other types...
   }

   private static IEnumerable<T> GetEnum<T>(string key)
   {
      // TODO: Return an enumerable...
   }
}

編集
必要なリターンタイプが実装され IEnumerable<>ているかどうかを確認する場合は、次を使用できます。

Type enumerable = typeof(T).GetInterface("System.Collections.Generic.IEnumerable`1");
if (enumerable != null)
{
   Type v = enumerable.GetGenericArguments()[0];
   var baseMethod = typeof(TheClass).GetMethod("GetEnum", flags);
   var realMethod = baseMethod.MakeGenericMethod(v);
   return (T)(object)realMethod.Invoke(null, new[] { key });
}

ただし、GetEnum<V>メソッドはにキャストできる値を返すT必要があります。そうしないと、無効なキャスト例外が発生します。

たとえば、メソッドがをGetEnum<V>返す場合、メソッドは、new List<T>(...)またはによって実装されたインターフェイスのGet<T>場合にのみ機能します。を呼び出すと、失敗します。TList<T>List<T>Get<HashSet<int>>

于 2013-03-21T20:39:06.957 に答える