Получить тип универсального интерфейса?
Я получил общий интерфейс вроде этого:
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 должно обновить ваше выражение поиска.