Страницы

Поиск по вопросам

суббота, 21 марта 2020 г.

Проверить генерик-тип интерфейса в C#?

#c_sharp #net #рефлексия #net_core


У меня есть тип AType который реализует генерик-интерфейс IA
Тип BType реализует интерфейс IC.
Как я могу проверить связан AType с IC или нет?

class AType : IA
{}

class BType : IC
{}

interface IA
{ }

interface IC
{ }


Тип BType может быть любым и мне о нем ничего неизвестно. У меня есть экземпляр AType
и мне нужно понять реализует ли он IC через generic тип промежуточного интерфейса IA
Проверка ниже не работает: 

var aInstance = new AType();
aInstance is IA // false
...


Также для Type.IsAssignableFrom(Type)

typeof(IC).IsAssignableFrom(aInstance.GetType()) // false

    


Ответы

Ответ 1



Проверка ниже не работает: Верно, потому что компилятор ничего не знает о вариантности интерфейса. Если ваш интерфейс IA фактически является ковариантным, то укажите это явно: interface IA { } потом: var aInstance = new AType(); Console.WriteLine(aInstance is IA); // True Но явная вариантность — это ограничение и интерфейс может считаться ковариантным только в случае когда все его члены используют тип T только для возврата. Скомпилируется: interface IA { T Method(); } Не скомпилируется: interface IA { void Method(T t); } подробно: Вариативность в универсальных интерфейсах (C#) Если ваш тип не является ковариантным, то вам придется разбирать это явно. Для проверок внутри класса можно написать что-то вроде: class AType : IA { public bool HasParamenterOfTypeIC() { return typeof(IC).IsAssignableFrom(typeof(T)); } } тогда: var a = new AType(); Console.WriteLine(a.HasParamenterOfTypeIC()); // True var b = new AType(); Console.WriteLine(b.HasParamenterOfTypeIC()); // False для проверок снаружи вы должны еще и явно достать дженерик-параметр и проверить его на совместимость: class OType : IA { } class AType : IA { } class Program { static void Main() { Console.WriteLine(HasParamenterOfTypeIC(typeof(AType))); // True Console.WriteLine(HasParamenterOfTypeIC(typeof(OType))); // False } static bool HasParamenterOfTypeIC(Type type) { return type .GetInterfaces() .SelectMany(i => i.GetGenericArguments()) .Any(i => typeof(IC).IsAssignableFrom(i)); } }

Комментариев нет:

Отправить комментарий