简体   繁体   English

开放实现的开放通用接口类型不等于接口类型吗?

[英]Open generic interface types of open implementation don't equal interface type?

Here's a test that should, in my opinion be passing but is not. 我认为这是一个应该通过但没有通过的测试。

[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. Why does this not pass? 为什么不通过?
  2. Given Type t = typeof(OpenGenericWithOpenService<>) how do I get typeof(IGenericService<>)? 给定Type t = typeof(OpenGenericWithOpenService<>)我如何获得typeof(IGenericService <>)?

I'm generally curious, but if you're wondering what I'm doing, I'm writing a Structuremap convention that forwards all interfaces implemented by a class to the implementation (as a singleton). 我通常很好奇,但是如果您想知道我在做什么,我正在写一个Structuremap约定,该约定将由类实现的所有接口转发给实现(作为单例)。

OpenGenericWithOpenService<T> doesn't implement just an arbitrary IGenericService<> - it implements IGenericService<T> for the same T as the class. OpenGenericWithOpenService<T>不仅实现了任意的 IGenericService<> ,而且还实现了与类相同的T IGenericService<T>

The best way to show this is to change the class slightly: 证明这一点的最佳方法是稍微更改类:

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

Now it's important that when you ask that for the interfaces it implements, you know that you can convert to IGenericService<T1> but (coincidences aside) not IGenericService<T2> or any other implementation. 现在很重要的一点是,当您要求它实现的接口时,您知道可以转换为IGenericService<T1>但是(巧合的是) 不能转换为IGenericService<T2>或任何其他实现。

In other words, it's not entirely open - it's pinned down to the same type argument that the class has. 换句话说,它不是完全开放的,而是固定在类具有的相同类型参数上。

I've never been very good with the generics terminology, but I hope you see what I mean. 我从来都不擅长使用泛型术语,但是希望您明白我的意思。 IGenericService<> is a type waiting to be given a type argument; IGenericService<>是一种类型,需要等待为其提供类型IGenericService<> in this case you've got the type argument - it just happens to be another type parameter! 在这种情况下,您 type参数-它恰好是另一个type参数!

Here's a test which will pass: 这是将通过的测试:

[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);
}

If you change the class to implement (say) IGenericService<int> instead, it will fail. 如果您更改类以实现(例如) IGenericService<int> ,则它将失败。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM