打开通用接口类型的开放实现不等于接口类型?
这是一个在我看来应该通过但不是的测试。打开通用接口类型的开放实现不等于接口类型?
[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> { }
- 为什么会出现这种不通过?
- 鉴于
Type t = typeof(OpenGenericWithOpenService<>)
如何获得typeof(IGenericService <>)?
我一般很好奇,但是如果你想知道我在做什么,我正在编写一个Structuremap约定,将实现的所有接口转发给实现(作为单例)。
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>
相反,它会失败。
是的。刚刚在这里发现更多:http://*.com/questions/511620/generic-types-not-equal 如果我使用typeof(OpenGenericWithOpenService )。GetInterfaces()。First()。 GetGenericTypeDefinition()' – 2010-04-20 20:35:16
仍然不明白为什么'OpenGenericWithOpenService '没有实现'IGenericService '...? – thecoop 2010-04-20 20:35:18
太棒了!我发现关于泛型的反射语义(开放或其他)的推理很复杂。我认为这个问题值得在一本书中处理。嗯,我们知道谁可以做到这一点...... :) – LBushkin 2010-04-20 20:37:32
破解问题。调查:) – 2010-04-20 20:25:27
如果你真的想让测试通过,你可以比较GUID。 – 2010-04-20 20:33:56