Получение аргументов типа универсальных интерфейсов, которые реализует класс - PullRequest
29 голосов
/ 17 июля 2009

У меня есть общий интерфейс, скажем, IGeneric. Для данного типа я хочу найти общие аргументы, которые класс реализует через IGeneric.

В этом примере это более понятно:

Class MyClass : IGeneric<Employee>, IGeneric<Company>, IDontWantThis<EvilType> { ... }

Type t = typeof(MyClass);
Type[] typeArgs = GetTypeArgsOfInterfacesOf(t);

// At this point, typeArgs must be equal to { typeof(Employee), typeof(Company) }

Какова реализация GetTypeArgsOfInterfacesOf (Тип t)?

Примечание. Можно предположить, что метод GetTypeArgsOfInterfacesOf написан специально для IGeneric.

Редактировать: Обратите внимание, что я специально спрашиваю, как отфильтровать интерфейс IGeneric от всех интерфейсов, которые реализует MyClass.

Связанный: Определение, реализует ли тип универсальный интерфейс

Ответы [ 3 ]

40 голосов
/ 17 июля 2009

Чтобы ограничить его только определенным видом универсального интерфейса, вам нужно получить определение универсального типа и сравнить его с «открытым» интерфейсом (IGeneric<> - обратите внимание, что «T» не указано):

List<Type> genTypes = new List<Type>();
foreach(Type intType in t.GetInterfaces()) {
    if(intType.IsGenericType && intType.GetGenericTypeDefinition()
        == typeof(IGeneric<>)) {
        genTypes.Add(intType.GetGenericArguments()[0]);
    }
}
// now look at genTypes

Или как синтаксис запроса LINQ:

Type[] typeArgs = (
    from iType in typeof(MyClass).GetInterfaces()
    where iType.IsGenericType
      && iType.GetGenericTypeDefinition() == typeof(IGeneric<>)
    select iType.GetGenericArguments()[0]).ToArray();
16 голосов
/ 17 июля 2009
typeof(MyClass)
    .GetInterfaces()
    .Where(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IGeneric<>))
    .SelectMany(i => i.GetGenericArguments())
    .ToArray();
2 голосов
/ 17 июля 2009
  Type t = typeof(MyClass);
            List<Type> Gtypes = new List<Type>();
            foreach (Type it in t.GetInterfaces())
            {
                if ( it.IsGenericType && it.GetGenericTypeDefinition() == typeof(IGeneric<>))
                    Gtypes.AddRange(it.GetGenericArguments());
            }


 public class MyClass : IGeneric<Employee>, IGeneric<Company>, IDontWantThis<EvilType> { }

    public interface IGeneric<T>{}

    public interface IDontWantThis<T>{}

    public class Employee{ }

    public class Company{ }

    public class EvilType{ }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...