Нет. Вы столкнулись с проблемой общей дисперсии, которая не поддерживается в .NET, за исключением нескольких очень специфических способов.
Вот причина: после последней строки у вас есть один словарь с двумя «взглядами» на него. Теперь представьте, что вы написали:
DictA.Add(1, New A())
(Прошу прощения, если мой VB слегка отключен.) Это вставило «не-B» в словарь, но DictB считает, что все значения будут экземплярами B.
Одной из основных целей обобщений является обнаружение потенциальных сбоев типов во время компиляции, а не во время выполнения, что означает, что этот код не должен компилироваться, что на самом деле происходит именно из-за отсутствия дисперсии.
Это немного нелогично, когда вы привыкли к нормальному наследованию, но это имеет смысл. Связка бананов - это не просто сбор фруктов - это сбор бананов .
Java занимает несколько иную позицию в этом вопросе, используя подстановочные знаки со стороны вызывающей стороны - это позволит вам увидеть только сторону «добавления» словаря для DictB, например, поскольку все, что вы добавляете в DictB, будет хорошо в DictA. Хотя дженерики Java сильно отличаются от дженериков .NET ...