C # Отсутствие статического наследования - что мне делать? - PullRequest
7 голосов
/ 09 апреля 2010

Хорошо, как вы, наверное, знаете, статическое наследование невозможно в C #. Я понимаю это, однако я застрял с развитием моей программы.

Я постараюсь сделать это как можно проще. Допустим, нашему коду необходимо управлять объектами, которые представляют самолеты в каком-то аэропорту. Требования следующие:

  • Есть члены и методы, которые являются общими для всех воздушных судов

  • Существует много типов самолетов, у каждого типа могут быть свои дополнительные методы и члены. Может быть много экземпляров для каждого типа самолета.

  • У каждого типа воздушного судна должно быть понятное имя для этого типа и более подробная информация об этом типе. Например, класс с именем F16 будет иметь статический член FriendlyName со значением «Lockheed Martin F-16 Fighting Falcon».

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

  • В некоторых графических интерфейсах должен быть способ, позволяющий пользователю просматривать список доступных типов (с такими сведениями, как FriendlyName), а также добавлять или удалять экземпляры самолетов, сохраненные, скажем, в некоторый XML файл.

Таким образом, в принципе, если бы я мог принудительно применять унаследованные классы для реализации статических членов и методов, я бы обеспечил, чтобы типы самолетов имели статические члены, такие как FriendlyName. К сожалению, я не могу этого сделать.

Итак, что будет лучшим дизайном для этого сценария?

Ответы [ 7 ]

8 голосов
/ 09 апреля 2010

Один из ответов - украсить каждый класс атрибутами (метаданными):

[Description("Lockheed Martin F-16 Fighting Falcon")]
public class F16 : Aircraft
{
    // ...
}

Это использует Описание атрибута уже в System.ComponentModel.

Вы можете получить метаданные следующим образом:

Type t = typeof(F16);
DescriptionAttribute attr = (DescriptionAttribute)Attribute.GetCustomAttribute(t,
    typeof(DescriptionAttribute));
string description = (attr != null) ? attr.Description : t.Name;

Это даст вам текст описания из ссылки на класс F16.

4 голосов
/ 09 апреля 2010

Зачем вам нужны эти свойства, чтобы быть статичными?

public class Aircraft
{
protected string AircraftName { get; protected set; }
}

public class F16 : Aircraft
{
   public F16()
   {
     AircraftName="F16 Falcon";
   }
}
3 голосов
/ 09 апреля 2010

Не используйте статические методы. вместо этого используйте методы экземпляра.

Также в верхнем реферате может быть представлен абстрактный метод, который возвращает конкретное имя самолета.

public abstract class Aircraft
{
    public abstract string Name { get; }
    public abstract string FriendlyName { get; }
}
2 голосов
/ 09 апреля 2010

Это тот случай, когда вы можете воспользоваться паттерном Factory. Вместо импорта определенных типов самолетов, предоставьте стандартный интерфейс IAircraftFactory, который определяет, что каждый авиационный завод должен сделать для вас. Здесь вы можете вернуть описания, информацию о пользовательском интерфейсе и т. Д. Авиастроительная фабрика отвечает за создание конкретного самолета. Поскольку ваши клиенты должны создать собственную Фабрику, чтобы выставить свои самолеты, они вынуждены внедрить интерфейс и напомнили (через его участников), что у них есть контракт для выполнения.

Что-то вроде:

public interface IAircraft
{
    //Aircraft instance details...
}

public interface IAircraftFactory
{
    //Can include parameters if needed...
    IAircraft BuildAircraft();

    //And other useful meta-data...
    string GetDescription();
}

//In some other Client-provided DLL...
public class MyAircraftFactory : IAircraftFactory
{
    IAircraft BuildAircraft()
    {
        return new MyAircraft();
    }

    //...
}
1 голос
/ 09 апреля 2010

Используйте перечисление для понятных имен и создайте элемент экземпляра этого типа для понятного имени. Требуется инициализация этого члена во время строительства.

0 голосов
/ 12 июня 2012

Интересным способом решения этой проблемы является признание того, что типы самолетов также являются важной концепцией в конструкции, и создание их как отдельных классов , чьи экземпляры действуют как типы из самолетов . Это известно как шаблон объекта типа (pdf) , и оно допускает очень гибкие конструкции.

0 голосов
/ 12 июня 2012

@ Aaronaught ударил по голове гвоздем с подобным плагину комментарием архитектуры.

Что я делал в прошлый раз, когда столкнулся с этим, так это имел тип «Дескриптор», который не очень дорого создавать, и держал метаданные в поле экземпляра.

public class F16Descriptor : AircraftDescriptor
{
    public override string Name { get { return "Lockheed Martin F-16 Fighting Falcon"; } }
    public override Type AircraftType { get { return typeof(F16); } }
}

public class F16 : AircraftBase
{
    ...
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...