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

故事扮演 提交于 2021-02-04 17:17:49

问题


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<>)?

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).


回答1:


OpenGenericWithOpenService<T> doesn't implement just an arbitrary IGenericService<> - it implements IGenericService<T> for the same T as the class.

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.

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; in this case you've got the type argument - it just happens to be another type parameter!

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.



来源:https://stackoverflow.com/questions/2678336/open-generic-interface-types-of-open-implementation-dont-equal-interface-type

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!