Luca Clavarino
Luca Clavarino

Reputation: 434

Working around the lack of enum inheritance

Classes Phone and Computer both implement the IDevice interface.

Phone has a PhoneStatus enum property, while Computer has a ComputerStatus enum property. Moreover, they both have a method that returns some stuff based on their status property.

class Phone : IDevice
{
    public string Name { get; set; }
    public string Manufacturer { get; set; }
    public PhoneStatus Status { get; set; }
    
    IEnumerable<object> GetStuffByStatus(PhoneStatus status)
    {
        ...
    }
}

enum PhoneStatus
{
    On,
    Off
}

class Computer : IDevice
{
    public string Name { get; set; }
    public string Manufacturer { get; set; }
    public ComputerStatus Status { get; set; }
    
    IEnumerable<object> GetStuffByStatus(ComputerStatus status)
    {
        ...
    }
}

enum ComputerStatus
{
    Started,
    ShutDown,
    Booting,
    ShuttingDown
}

I know inheritance is not an option for enums, so the question is: is there any way to force the classes implementing IDevice to write their own DeviceStatus property (which could be implemented as a PhoneStatus or a ComputerStatus) and GetStuffByStatus method? Something like this

interface IDevice
{
    string Name { get; set; }
    string Manufacturer { get; set;}
    DeviceStatus Status { get; set;}
    
    IEnumerable<object> GetStuffByStatus(DeviceStatus status);
}

Upvotes: 3

Views: 1093

Answers (1)

Matthew Watson
Matthew Watson

Reputation: 109577

You could try something like this:

public interface IDevice<T> where T: Enum
{
    string Name         { get; set; }
    string Manufacturer { get; set; }
    T Status { get; set; }

    IEnumerable<object> GetStuffByStatus(T status);
}

Then implementing classes must declare an enum of some kind for the status:

public class Computer: IDevice<ComputerStatus>
{
    public string Name { get; set; }
    public string Manufacturer { get; set; }
    public ComputerStatus Status { get; set; }

    public IEnumerable<object> GetStuffByStatus(ComputerStatus status)
    {
        throw new NotImplementedException();
    }
}

If you need to, you could extract the common parts that are not dependent on the Status enum into a base interface:

public interface IDevice
{
    string Name         { get; set; }
    string Manufacturer { get; set; }
}

public interface IDeviceWithStatus<T>: IDevice where T: Enum
{
    T Status { get; set; }
    IEnumerable<object> GetStuffByStatus(T status);
}

Then you'll still be able to access the common parts via IDevice and the status-dependent parts via IDeviceWithStatus<T>.

Upvotes: 2

Related Questions