Интерфейсы не могут объявлять типы

У меня есть абстрактный класс в API, который используется методами в другой сборке. Класс имеет вложенное перечисление, определенное внутри него, примерно так:

abstract public class Thing
{
    public enum Status { Accepted, Denied, Pending };
    abstract public Status status { get; private set; }
    etc...
}

Тогда я решил, что это будет лучший дизайн, если Thing будет интерфейсом. Но я не могу этого сделать:

public interface Thing
{
    enum Status { Accepted, Denied, Pending };
    Status status { get; }
    etc...
}

Появится сообщение об ошибке "Интерфейсы не могут объявлять типы". Однако, если я переведу определение enum за пределами интерфейса, во-первых, я буду нарушать инкапсуляцию (тип Status действительно принадлежит Thing и сам по себе не имеет смысла), и, что более важно, мне пришлось бы пойти и изменить код в многие другие сборки, которые используют это. Можете ли вы придумать какие-либо решения?

Ответ 1

Как показывает ошибка, вам просто нужно вывести определение Status за пределы интерфейса. Я понимаю, что это разрушает инкапсуляцию, но на самом деле этого не происходит. Я предлагаю вам изменить имя Status на то, что указывает на сильное отношение к Thing - ThingStatus, чтобы сделать трюк.

enum ThingStatus { Accepted, Denied, Pending };

public interface Thing
{
    ThingStatus status { get; }
    etc...
}

Ответ 2

О да, решение состоит в том, чтобы использовать абстрактный класс, если вам нужна такая реализация. Абстрактные классы не плохой дизайн и, безусловно, полезны в таких ситуациях.

Если вы настаиваете на использовании интерфейсов, я боюсь, вам придется пойти с решением из p.s.w.g и нарушить правило или два (это все равно, как правило, на самом деле).

Ответ 3

abstract class и interface - это разные вещи. abstarct класс - это абстракция, выше вашей модели домена, а интерфейс - это контракт (поведение) вашего объекта домена. Вы можете использовать их в своем решении по мере необходимости. В конкретном сценарии status это не поведение, а просто состояние объекта. Я думаю, что абстрактный класс - более надежный выбор.