Получить тип универсального интерфейса?

Я получил общий интерфейс вроде этого:

public interface IResourceDataType<T>
{
    void SetResourceValue(T resValue);
}

Затем я получил этот класс, который реализует мой интерфейс:

public class MyFont : IResourceDataType<System.Drawing.Font>
{
    //Ctor + SetResourceValue + ...
}

И наконец я получил:

var MyType = typeof(MyFont);

Теперь я хочу получить тип System.Drawing.Font из MyType! На данный момент я получил этот код:

if (typeof(IResourceDataType).IsAssignableFrom(MyType))
{
    //If test is OK
}

Но мне не удается "извлечь" мой тип здесь... Я пробовал пару вещей с помощью GetGenericArguments() и других вещей, но они либо не компилируют, либо возвращают нулевое значение /List... Что мне делать?

ИЗМЕНИТЬ: Вот решение, которое соответствует моему коду тем, у кого будет такая же проблема:

if (typeof(IResourceDataType).IsAssignableFrom(MyType))
{
    foreach (Type type in MyType.GetInterfaces())
    {
        if (type.IsGenericType)
            Type genericType = type.GetGenericArguments()[0];
        }
    }
}

Ответы

Ответ 1

Поскольку ваш класс MyFont реализует только один интерфейс, вы можете написать:

Type myType = typeof(MyFont).GetInterfaces()[0].GetGenericArguments()[0];

Если ваш класс реализует несколько интерфейсов, вы можете вызвать метод GetInterface() с искаженным именем интерфейса, который вы ищете:

Type myType = typeof(MyFont).GetInterface("IResourceDataType`1")
                            .GetGenericArguments()[0];

Ответ 2

var fontTypeParam = typeof(MyFont).GetInterfaces()
    .Where(i => i.IsGenericType)
    .Where(i => i.GetGenericTypeDefinition() == typeof(IResourceDataType<>))
    .Select(i => i.GetGenericArguments().First())
    .First()
    ;

Это позаботится о том, чтобы вы переименовали интерфейс. Там нет строкового литерала, поэтому переименование в Visual Studio должно обновить ваше выражение поиска.