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

98
14 июля 2021, 14:00

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

class AType : IA<BType>
{}
class BType : IC
{}
interface IA<T>
{ }
interface IC
{ }

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

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

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

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

Проверка ниже не работает:

Верно, потому что компилятор ничего не знает о вариантности интерфейса.

Если ваш интерфейс IA<T> фактически является ковариантным, то укажите это явно:

interface IA<out T> { }

потом:

var aInstance = new AType();
Console.WriteLine(aInstance is IA<IC>); // True

Но явная вариантность — это ограничение и интерфейс может считаться ковариантным только в случае когда все его члены используют тип T только для возврата.
Скомпилируется:

interface IA<out T>
{
    T Method();
}

Не скомпилируется:

interface IA<out T>
{
    void Method(T t);
}

подробно: Вариативность в универсальных интерфейсах (C#)

Если ваш тип не является ковариантным, то вам придется разбирать это явно.

Для проверок внутри класса можно написать что-то вроде:

class AType<T> : IA<T>
{
    public bool HasParamenterOfTypeIC()
    {
        return typeof(IC).IsAssignableFrom(typeof(T));
    }
}

тогда:

var a = new AType<BType>();
Console.WriteLine(a.HasParamenterOfTypeIC()); // True
var b = new AType<object>();
Console.WriteLine(b.HasParamenterOfTypeIC()); // False

для проверок снаружи вы должны еще и явно достать дженерик-параметр и проверить его на совместимость:

class OType : IA<object> { }
class AType : IA<BType> { }
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));
    }
}
READ ALSO
Как изменить мета тег Title в админке WordPress?

Как изменить мета тег Title в админке WordPress?

Как изменить заголовок именно в админке WordPress? Нужно убрать именно слово "WordPress", которое добавляется после заголовка на каждой странице в админкеМожет,...

88
Телеграмм не отправляет запрос через webhook

Телеграмм не отправляет запрос через webhook

При отправке сообщения боту не отправляется запрос через webhookWebhook успешно установил, у домена есть SSL-сертификат от Let's Encrypt, рейтинг А

97
Авторизация через Госуслуги

Авторизация через Госуслуги

Пробую сделать авторизацию через ГосуслугиПорядок подключения сайта понятен

124