开发者

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

开发者 https://www.devze.com 2022-12-27 08:45 出处:网络
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()

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(IGener开发者_如何学JAVAicService<>));
}
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).


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消