代码之家  ›  专栏  ›  技术社区  ›  George Mauer

开放实现的开放泛型接口类型不等于接口类型?

  •  10
  • George Mauer  · 技术社区  · 15 年前

    在我看来,这是一个应该通过但却没有通过的测试。

    [TestMethod]
    public void can_get_open_generic_interface_off_of_implementor()
    {
        typeof(OpenGenericWithOpenService<>).GetInterfaces().First()
            .ShouldEqual(typeof(IGenericService<>));
    }
    public interface IGenericService<T> { }
    public class OpenGenericWithOpenService<T> : IGenericService<T> { }
    
    1. 为什么不通过?
    2. 鉴于 Type t = typeof(OpenGenericWithOpenService<>) 如何获取类型(igenericservice<>)?

    我通常很好奇,但是如果您想知道我在做什么,我正在编写一个structuremap约定,它将一个类实现的所有接口转发给实现(作为单例)。

    1 回复  |  直到 15 年前
        1
  •  7
  •   Jon Skeet    15 年前

    OpenGenericWithOpenService<T> 不只是实现 任意的 IGenericService<> -它实现了 IGenericService<T> 为了同样 T 作为全班同学。

    最好的方法是稍微改变类:

    public class OpenGenericWithOpenService<T1, T2> : IGenericService<T1> {}
    

    现在很重要的一点是,当你要求它实现接口时,你知道你可以转换成 IGenericService<T1> 但是(巧合除外) IGenericService<T2> 或任何其他实现。

    换句话说,它不是完全打开的——它被固定在类具有的相同类型参数上。

    我对泛型术语从来就不是很在行,但我希望你明白我的意思。 igenericservice<> 是等待给定类型参数的类型;在这种情况下 得到了 类型参数-它恰好是另一个类型参数!

    下面是一个将通过的测试:

    [TestMethod]
    public void can_get_open_generic_interface_off_of_implementor()
    {
        Type[] typeParams = typeof(OpenGenericWithOpenService<>).GetGenericArguments();
        Type constructed = typeof(IGenericService<>).MakeGenericType(typeParams);
        typeof(OpenGenericWithOpenService<>).GetInterfaces().First()            
            .ShouldEqual(constructed);
    }
    

    如果您将类更改为实现(例如) IGenericService<int> 相反,它将失败。

    推荐文章