I have an "inheritance-tree" which looks like this:
There is common code for the "TargetWithTeststand" and i would like to have a common code source. My only idea would be to use a separate static class and gather the methods which are common. Another idea was to use a common interface with default methods, but this does not support override.
Do you have any better idea how to deal with such inheritance problems?
Here is a code example:
using System;
public class Program
{
public static void Main()
{
int deviceType = 1; // This value is read from a config file which can be changed
Device device = null;
switch (deviceType)
{
case 0:
device = new TargetWithTeststandDev1();
break;
case 1:
device = new TargetWithSimulationDev2();
break;
// [....]
}
device.ReadMotorSpeed();
device.UsePowerButton();
}
}
public abstract class Device
{
public virtual void UsePowerButton()
{
throw new NotImplementedException();
}
public virtual void ReadMotorSpeed()
{
throw new NotImplementedException();
}
}
public abstract class DeviceType1 : Device
{
public override void ReadMotorSpeed()
{
Console.WriteLine("Read motor speed with DeviceType1");
}
}
public abstract class DeviceType2 : Device
{
public override void ReadMotorSpeed()
{
Console.WriteLine("Read motor speed with DeviceType2");
}
}
public sealed class TargetWithTeststandDev1 : DeviceType1
{
public override void UsePowerButton()
{
Console.WriteLine("UsePowerButton on teststand with DeviceType1");
}
}
public sealed class TargetWithSimulationDev1 : DeviceType1
{
public override void UsePowerButton()
{
Console.WriteLine("UsePowerButton on teststand with DeviceType1");
}
}
public sealed class TargetWithTargetDev1 : DeviceType1
{
public override void UsePowerButton()
{
Console.WriteLine("UsePowerButton on Target with DeviceType1");
}
}
public sealed class TargetWithTeststandDev2 : DeviceType2
{
public override void UsePowerButton()
{
Console.WriteLine("UsePowerButton on Simulation with DeviceType2");
}
}
public sealed class TargetWithSimulationDev2 : DeviceType2
{
public override void UsePowerButton()
{
Console.WriteLine("UsePowerButton on Simulation with DeviceType2");
}
}
public sealed class TargetWithTargetDev2 : DeviceType2
{
public override void UsePowerButton()
{
Console.WriteLine("UsePowerButton on Target with DeviceType2");
}
}
CodePudding user response:
You have literally drawn the diamond problem, One of the main reasons multiple inheritance is not supported.
The typical solution to this is to use composition instead of inheritance. I.e. gather all the common functions for a simulation in a separate class, that your SimulationDev1 and SimulationDev2 classes refer to, and any simulation operations would be delegated to this class.
An alternative would be to use interfaces and extension methods or default interface implementations to do more or less the same thing:
public interface ISimulation
{
int AProperty { get; }
}
public static class SimulationExtensions
{
public static int SomeCommonMethod(this ISimulation self, int b) => self.AProperty b;
}