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>
, он потерпит неудачу.