Можно ли принудительно переопределить элемент, не помеченный как виртуальный или абстрактный, с производным типом? - PullRequest
2 голосов
/ 15 сентября 2011

Я видел это , но мне интересно, можно ли было бы принудительно переопределить элемент, не помеченный как виртуальный или абстрактный с производным типом (следовательно, это не должно нарушать функциональности базового объекта).

Я имею в виду, в частности, переопределение:

IDictionary<TKey, TValue> Dictionary { get; }

в

KeyedCollection<TKey, TValue> 

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

Можно ли вообще обойти ограничение?

Обратите внимание, что я не хотел бы использовать расширения для этого (в моем случае это не помогло бы в любом случае).

Ответы [ 3 ]

5 голосов
/ 15 сентября 2011

Нет. В .net метод должен быть помечен как явно виртуальный или абстрактный, чтобы переопределить его.

РЕДАКТИРОВАТЬ: Учитывая изменения в вопросе, кажется, что вам нужно создать собственный класс, который реализует IDictionary<TKey, TValue> (что, я думаю, KeyedCollection делает), затем добавьте еще один индексатор, который позволяет получать объекты по TKey.Индексатор будет выглядеть следующим образом:

TValue this[TKey key] { get { ... } }

Если вы хотите, вы можете вернуть практически все методы и свойства IDictionary, делегировав частное поле KeyedCollection<TKey, TValue>, а для тех, которые вы хотите реализовать по-другому, выбыл бы свободен сделать это.Полный класс был бы слишком длинным для ответа, в противном случае я бы опубликовал его.

Это идет к хорошей практике разработки Предпочитают композицию по наследованию

3 голосов
/ 15 сентября 2011

Если .NET в этом отношении похож на c ++, то это физически невозможно, поскольку виртуалы реализованы как указатели на функции, а не виртуалы - как фиксированные адреса функций.

Итак, НЕТ.

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

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

0 голосов
/ 15 сентября 2011

Как сказали другие ответы, вы не можете переопределить в производном классе, но вы можете скрыть базовую реализацию:

static void Main(string[] args)
{
    Console.WriteLine("Animal: {0}", new Animal().NumberOfLegs);
    Console.WriteLine("Caterpillar: {0}", new Caterpillar().NumberOfLegs);

    Console.ReadKey();
}

public class Animal
{
    public int NumberOfLegs { get { return 1; } }
}

public class Caterpillar : Animal
{
    public new int NumberOfLegs { get { return 100; } }
}
...