Допустим, у меня есть два класса 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 #.
Я упускаю что-то очевидное здесь ? Любые идеи? Спасибо.