The class Volume is described. Volume contains an attribute as an object. This object can have either the type BootFAT16 or BootFAT32 or BootNTFS, and before using this object, which type to assign will be clear from the condition. And in the future, depending on the type of object, it will be processed differently. (I cannot use the interface, since many methods have different signatures) How are such situations solved? What mechanisms apply?

  • five
    I would try to encapsulate work with Boot* into separate objects (with a common interface), and would work through this interface. The data needed for “methods with different signatures” should also be accumulated in these objects. - VladD
  • And what is the difficulty in allocating the common part to the interface, and then through the conditions check GetType() and do actions specific for the object? - ArchDemon
  • Check the type during the execution of the program and further undertake the necessary logic depending on the type. Implement Type Check - Exodium
  • @VladD answer with an example? - andreycha
  • @andreycha: It’s hard to explain how to reduce, in general, actions with seemingly different parameters to an action with the same ones. It would be better if the TS gave an example of the code. - VladD

2 answers 2

I think that the switch option is not very convenient. You can use the dictionary with delegates. It is more convenient to add new handlers.

  public void ProcessBootCommon(object value) { var bootType = value.GetType(); //проверка на наличие нужного обработчика if (!BootProcessors.ContainsKey(bootType)) return; var processor = BootProcessors[bootType]; //вызов обработчика processor.Invoke(value); } private Dictionary<Type, Action<object>> BootProcessors = new Dictionary<Type, Action<object>> { { typeof(BootFat16), ProcessBootFat16} //и так далее для каждого типа. Легко добавлять новые обработчики, если вдруг появятся новые типы }; private void ProcessBootFat16(object value) { //Пост проверка. На всякий случай if(value.GetType() != typeof(BootFat16)) return; //Код обработки } 

    In C #, all types are inherited from the base type of object, use it. Your code will be something like this (C # 7):

     void UseVolume(object volume) { switch(volume) { case BootFat16 bootFat16: BootFat16VolumeProcessor.Process(bootFat16); break; case BootFat32 bootFat32: BootFat32VolumeProcessor.Process(bootFat32); break; case BootNtfs bootNtfs: BootNtfsVolumeProcessor.Process(bootNtfs); break; default: throw new InvalidOperationException("Unknown volume type"); } }