Как использовать полиморфизм или наследование в статических классах? - PullRequest
3 голосов
/ 15 февраля 2012

Слушай, я знаю, что статические классы не могут наследовать или реализовывать.Вопрос в том, «что, черт возьми, является правильным C # + ООП-шаблоном для реализации этого?».«Это» описано ниже:

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

// Theoritical; static classes can't actually implement
interface IBaseConverter { 
    int Base { get; }
    char[] Glyphs { get; }
    int ToInt(string value);
    string FromInt(int value);
}

// AND / OR (interface may be superfluous)
public class BaseConverter : IBaseConverter{ 
    public BaseConverter(int Base, char[] Glyphs) {
        this.Base = Base;
        this.Glyphs = Glyphs;
    }
    public int Base { get; private set; }
    public char[] Glyphs { get; private set;}
    public int ToInt(string value) { // shared logic...
    public string FromInt(int value) { // shared logic...
}

Они также могут использовать одну и ту же логику реализации на основе значения Base и упорядоченного набораглифы.Например, Base16Converter будет иметь Base = 16 и glyphs = { '0', '1', ... 'E', 'F' }.Я верю, что FromInt и ToInt говорят сами за себя.Очевидно, что мне не нужно было бы реализовывать конвертер для базы 16, но мне do нужно реализовать конвертер для базовой базы 36 отрасли (глифы 0 - Z Code 39).Как и в случае встроенных функций преобразования и форматирования строк, таких как [Convert]::ToInt32("123",16), это абсолютно статические методы - , когда основание и глифы предварительно определены .

Я хочу сохранить версию экземпляра, которая может быть инициализирована с произвольными глифами и основанием, например:

BaseConverter converter = new BaseConverter(7, new[]{ 'P', '!', 'U', '~', 'á', '9', ',' })
int anumber = converter.ToInt("~~!,U")  // Equals 8325

Но я также хочу класс static дляBase36Code39Converter.Еще один способ объяснить это так: у любых static разработчиков просто есть жестко запрограммированная база и глифы:

// Theoritical; static classes can't inherit 
public static class Base36Code39Converter : BaseConverter {
    private static char[] _glyphs = { '0', '1', ... 'Z' }; 
    static Base36Code39Converter : base(36, _glyphs) { }
}

Я могу понять, почему это не сработает для компилятора - vtable для static не существуетметоды и все такое.Я понимаю, что в C # статический класс не может реализовывать интерфейсы или наследовать от чего-либо (кроме объекта) (см. Почему C # не позволяет статическим методам реализовывать интерфейс? , Почему я не могунаследовать статические классы? ).

Так какого черта является"правильным" C # + ООП-шаблоном для реализации этого?

Ответы [ 4 ]

3 голосов
/ 15 февраля 2012

Направление, в котором вы идете ... Не очень хорошая идея.

Я бы предложил вам подражать шаблону, представленному System.Text.Encoding .

Имеет открытые статические свойства типа Encoding, которые являются стандартными реализациями класса Encoding для различных типов кодирования текста.

  • ASCII
    • Получает кодировку для набора символов ASCII (7 бит).
  • BigEndianUnicode
    • Получает кодировку для формата UTF-16, в котором используется порядок байтов с прямым порядком байтов.
  • По умолчанию
    • Получает кодировку для текущей кодовой страницы ANSI операционной системы.
  • Unicode
    • Получает кодировку для формата UTF-16, используя порядок байтов с прямым порядком байтов.
  • UTF32
    • Получает кодировку для формата UTF-32, используя порядок байтов с прямым порядком байтов.
  • UTF7
    • Получает кодировку для формата UTF-7.
  • UTF8
    • Получает кодировку для формата UTF-8.

В вашем случае вы бы предоставили абстрактный базовый класс вместо интерфейса и выставили бы ваши общие реализации в качестве статических свойств.

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

2 голосов
/ 15 февраля 2012

Вы всегда можете использовать композицию. В этом случае ваш статический класс будет иметь экземпляр соответствующего конвертера и просто прокси-вызовы для этого:

public static class Base36Code39Converter
{
    private static BaseConverter _conv = 
        new BaseConverter(36, new[]{ '0', '1', ... 'Z' });

    public static int ToInt(string val)
    {
        return _conv.ToInt(val);
    }
}
1 голос
/ 16 марта 2012

Ответом был образец Синглтона. См. Например Реализация Singleton в C # .

Луиджи Мендоса предоставил этот ответ, который я пометил как ответ, но затем он почему-то удалил его. Я публикую это для полноты.

1 голос
/ 15 февраля 2012

Почему вы хотите сделать это статичным?

Singleton , кажется, то, что вы ищете.

...