C # : Как запретить неявное приведение от дочернего к родительскому классу (т. Е. Наследование по типу композиции или по типу)?

Резюме

Допустим, у меня есть два класса C # 4.0, один наследующий от другого:

class ParentKey {}
class ChildKey : ParentKey {}

Я хочу, чтобы компилятор выдал ошибку, если я попробую следующее:

ChildKey c = new ChildKey();
ParentKey p = c; // I want compiler error here!

По сути, я хочу использовать наследование для целей повторного использования , но я хочу избегать полиморфного поведения (или более в частности, назначьте совместимость), которая обычно идет с ним. Подобно частному наследованию C ++.


Пример

В частности, я хотел бы избежать случайного смешивания ParentKey и ChildKey при использовании в качестве ключей некоторого контейнера (поскольку их реализации GetHashCode () или Equals () могут быть несовместимы). Например:

Dictionary<ParentKey, object> d = new Dictionary<ParentKey, object>();
d.Add(new ChildKey(), new object()); // I want compiler error here!

Что я пробовал

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

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

Попытка сделать преобразование явным ...

class ChildKey : ParentKey {
    public static explicit operator ParentKey(ChildKey c) {
        // ...
    }
}

... привела к ошибке компилятора CS0553: определяемые пользователем преобразования в базовый класс или из него не разрешены.

Наследование структуры здесь было бы идеальным (так что «конечная» часть ChildKey «отсекается» при передаче чему-то, что объявлено как ParentKey), но это также не поддерживается в C #.

Я упускаю что-то очевидное здесь ? Любые идеи? Спасибо.

5
задан Branko Dimitrijevic 15 July 2011 в 16:24
поделиться