获取泛型接口的类型?

17

我有一个通用的接口,就像这样:

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

接下来,我创建了一个实现我的接口的类:

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

最后,我获得了一个:
var MyType = typeof(MyFont);

我现在想从MyType获取System.Drawing.Font类型!目前,我有以下代码:

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

但是我无法在这里“提取”我的类型... 我尝试了一些使用GetGenericArguments()和其他方法的东西,但它们要么不能编译,要么返回null值/列表... 我该怎么做?

编辑: 以下是适用于我的代码的解决方案,对于那些遇到相同问题的人:

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

你看过这篇帖子吗:https://dev59.com/eXRB5IYBdhLWcg3wpoxm - Brad Christie
是的,还有另外几个问题,它们没有回答我的问题...我感觉我得使用GetInterfaces()并做一些其他的事情,我正在尝试中! - Guillaume Slashy
2个回答

13

由于你的MyFont类只实现了一个接口,你可以这样写:

Type myType = typeof(MyFont).GetInterfaces()[0].GetGenericArguments()[0];
如果您的类实现了多个接口,您可以使用相应接口的名称来调用 GetInterface() 方法: http://msdn.microsoft.com/en-us/library/ayfa0fcd.aspx
Type myType = typeof(MyFont).GetInterface("IResourceDataType`1")
                            .GetGenericArguments()[0];

这正是我尝试的内容,但我确实实现了多接口,那只是一个片段来暴露我的问题! - Guillaume Slashy
我会“编辑”最终解决方案,我接近成功了。 - Guillaume Slashy
你需要使用 GetInterface(),请参考我的更新答案。 - Frédéric Hamidi
使用了“IsGeneric”,请参见解决方案,这就是我的问题 :) 无论如何感谢您的帮助! - Guillaume Slashy
事实上,Frederic,你的解决方案是好的,但有没有一种比字符串更强大的方法?我的意思是,如果我重命名我的接口,编译器不会用你的代码说任何话:/ - Guillaume Slashy
我不确定它是否真正符合“更健壮”的标准,但是FindInterfaces()接受一个过滤器委托和一个条件参数,而不是一个字符串,因此如果您希望这样做,可以自己实现搜索算法。 - Frédéric Hamidi

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

这解决了您对接口重命名的担忧。由于没有字符串文字,因此在Visual Studio中进行重命名应该会更新您的搜索表达式。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接