В C # невозможно переопределить статический метод.Тем не менее, у меня есть некоторые специфичные для типа методы (вместо обычных методов экземпляра), и я хочу дать пользователю возможность переопределять эти методы и, кроме того, иметь возможность вызывать эти (переопределенные) методы из моего собственного кода, не зная о«переопределение», сделанное пользователем.Если бы метод был статическим, мне нужно было бы заранее знать имя типа класса пользователя, а это не то, что мне нужно.
Как реализовать методы, специфичные для типа, такие как Read
, Write
и GetLength
и разрешить переопределение?
Фон
Существует абстрактный класс Row
, чьи производные типы / классы представляют тип строки ичей экземпляр представляет фактическую строку и ее поля / данные в очень простой таблице.Каждый тип строки имеет фиксированную длину, и таблица - это просто ряд строк в файле.Классу Row
нужны три метода: методы Read
и Write
, которые выполняют свою очевидную функцию в потоке с заданным смещением, и метод GetLength
, который возвращает фиксированную длину типа строки.
Теперь пользователь может расширить мой класс Row
и предоставить реализации для Read
, Write
и GetLength
для его или ее определенного типа строки , а также полей и свойств, которые будут использоваться в егоили ее конкретный экземпляр строки .Например, класс SomeUserRow
может иметь 32-разрядное целочисленное поле и однобайтовое поле, фиксированную длину 5 байтов и соответствующую реализацию метода чтения и записи.
Методы
Прочитайте
Очевидный фабричный метод, связанный с типом, и поэтому я бы определил его в самом классе.Я бы сделал это static
, но тогда это нельзя переопределить.Тогда я мог бы сделать это protected abstract
и создать статический обобщенный метод Read<T>
для его вызова, как предложено в этого поста .Но мне также нужно иметь возможность вызывать этот метод из моего кода, не зная типа реализованного пользователем класса.Я не могу просто позвонить Row.Read<UserType>()
, потому что я еще не знаю о типах пользователя.
Запись
Возможный метод экземпляра, потому что большинство людей хотят написать существующий Row
в поток.Но имея Read
static, кажется странным делать Write
метод экземпляра.
GetLength
Не фабричный метод, но все же связанный с типом.Опять же, я бы сделал это статичным, но это предотвращает переопределение.Я могу выбрать метод экземпляра, который можно переопределить, но это неправильно делать в объектно-ориентированной среде: создание экземпляра просто для получения значения, которое не зависит от экземпляра (int length = new T().GetLength()
) а точнее по его типу.
Я также думал о переносе трех методов из классов в отдельный класс, но это все еще не решает проблему переопределения.Или иметь класс, который хранит список или словарь делегатов, указывающих на правильные методы.Он не допускает переопределения real (замена указателя метода в массиве делегатов - это не то, что я бы рассмотрел true overriding), и он перемещает специфичные для типа методы от типа, которыйЯ думаю, что это нехорошо с точки зрения разработчика: иметь два или более мест для изменения, когда вы просто хотите изменить тип.
Посредством отражения можно вызвать правильный статический метод для типа, нокогда я читал много строк, я обнаружил, что это слишком медленно.