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> { }
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).
Only generic classes can implement generic interfaces. Normal classes can't implement generic interfaces.
Generic Interfaces in Java are the interfaces that deal with abstract data types. Interface help in the independent manipulation of java collections from representation details. They are used to achieving multiple inheritance in java forming hierarchies. They differ from the java class.
It's often useful to define interfaces either for generic collection classes, or for the generic classes that represent items in the collection. To avoid boxing and unboxing operations on value types, it's better to use generic interfaces, such as IComparable<T>, on generic classes.
You can declare variant generic interfaces by using the in and out keywords for generic type parameters. ref , in , and out parameters in C# cannot be variant. Value types also do not support variance. You can declare a generic type parameter covariant by using the out keyword.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With