Advertisement
VirtualMaestro

Ковариантные и Контрвариантные интерфейсы

Feb 3rd, 2024 (edited)
1,236
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 4.17 KB | None | 0 0
  1. // Варианты используются для задания правил совместимости интерфейсов.
  2. //
  3. // - Ковариантные интерфейсы могут иметь только возвращаемые типы (return type) (модификатор out).
  4. // - Это всегда Upcast (напр. если возвращаемый тип BasicTank, то все производные типы (MediumTank,HeavyTank) будут приведены к BasicTank)
  5.  
  6. // - Контрвариантные интерфейсы могут иметь только входящие параметры. (модификатор in)
  7. // - Контравариантность - это способность использовать менее конкретный тип, чем заданный изначально.
  8. // - Это всегда Downcast (напр. если тип принимаемого параметра BasicAirplane, то в туда можно подставить все наследуемые типы (JetAirplane,StealthAirplane))
  9.  
  10. // Пример. Имеются фабрики по производству танков и самолетов.
  11.  
  12. public interface IMilitaryFactory<in TBlueprint, out TProduct>
  13. {
  14.     public TProduct Produce(TBlueprint blueprint);
  15. }
  16.  
  17. // Blueprints hierarchy
  18. public class SimpleBlueprint { }
  19. public class AdvancedBlueprint : SimpleBlueprint { }
  20.  
  21. // Basic war machine
  22. public class WarMachine { }
  23.  
  24. // Tanks hierarchy
  25. public class BasicTank : WarMachine { }
  26. public class MediumTank : BasicTank { }
  27. public class HeavyTank : MediumTank { }
  28.  
  29. // Airplane hierarchy
  30. public class BasicAirplane : WarMachine { }
  31. public class JetAirplane : BasicAirplane { }
  32. public class StealthAirplane : JetAirplane { }
  33.  
  34. //
  35. public class AllTanksFactory : IMilitaryFactory<SimpleBlueprint, BasicTank>
  36. {
  37.     // Метод может принять ВСЕ типы чертежа - SimpleBlueprint и AdvancedBlueprint
  38.     public BasicTank Produce(SimpleBlueprint blueprint)
  39.     {
  40.         // Метод может вернуть любой тип танка от LightTank и до HeavyTank
  41.         return null;
  42.     }
  43. }
  44.  
  45. public class OnlyHeavyTanksFactory : IMilitaryFactory<AdvancedBlueprint, HeavyTank>
  46. {
  47.     // Метод может принять ТОЛЬКО AdvancedBlueprint
  48.     public HeavyTank Produce(AdvancedBlueprint blueprint)
  49.     {
  50.         // Метод может вернуть ТОЛЬКО экземпляр класса  HeavyTank и его производные
  51.         return null;
  52.     }
  53. }
  54.  
  55. public class AllAirplaneFactory : IMilitaryFactory<SimpleBlueprint, BasicAirplane>
  56. {
  57.     // Метод может принять ВСЕ типы чертежа - SimpleBlueprint и AdvancedBlueprint
  58.     public BasicAirplane Produce(SimpleBlueprint blueprint)
  59.     {
  60.         // Метод может вернуть любой экземпляр класса начиная от BasicAirplane и до StealthAirplane
  61.         return null;
  62.     }
  63. }
  64.  
  65. public class ExceptBasicAirplaneFactory : IMilitaryFactory<AdvancedBlueprint, JetAirplane>
  66. {
  67.     // Метод может принять ТОЛЬКО AdvancedBlueprint
  68.     public JetAirplane Produce(AdvancedBlueprint blueprint)
  69.     {
  70.         // Метод может вернуть ТОЛЬКО экземпляр класса JetAirplane и его производные, то есть StealthAirplane.
  71.         return null;
  72.     }
  73. }
  74.  
  75. //
  76. public class GameManager
  77. {
  78.     private IMilitaryFactory<SimpleBlueprint, BasicTank> _allTankFactory = new AllTanksFactory();
  79.     private IMilitaryFactory<AdvancedBlueprint, HeavyTank> _onlyHeavyTankFactory = new OnlyHeavyTanksFactory();
  80.     private IMilitaryFactory<SimpleBlueprint, BasicAirplane> _allAirplaneFactory = new AllAirplaneFactory();
  81.     private IMilitaryFactory<AdvancedBlueprint, JetAirplane> _exceptBasicAirplaneFactory = new ExceptBasicAirplaneFactory();
  82.    
  83.     public GameManager()
  84.     {
  85.         ProduceWarMachine(_allTankFactory);
  86.         ProduceWarMachine(_onlyHeavyTankFactory);
  87.         ProduceWarMachine(_allAirplaneFactory);
  88.         ProduceWarMachine(_exceptBasicAirplaneFactory);
  89.     }
  90.  
  91.     public void ProduceWarMachine(IMilitaryFactory<AdvancedBlueprint, WarMachine> factory)
  92.     {
  93.         WarMachine machine = factory.Produce(new AdvancedBlueprint());
  94.     }
  95. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement