Преобразование типа значения словаря в VB.net - PullRequest
0 голосов
/ 29 января 2009
Public Class A

Public Class B : Inherits A

Dim DictA As Dictionary(Of Integer, A)
Dim DictB As New Dictionary(Of Integer, B)

DictA = DictB

Это не работает, так как тип не может быть преобразован. Это как-то возможно?

Ответы [ 3 ]

4 голосов
/ 29 января 2009

Нет. Вы столкнулись с проблемой общей дисперсии, которая не поддерживается в .NET, за исключением нескольких очень специфических способов.

Вот причина: после последней строки у вас есть один словарь с двумя «взглядами» на него. Теперь представьте, что вы написали:

DictA.Add(1, New A())

(Прошу прощения, если мой VB слегка отключен.) Это вставило «не-B» в словарь, но DictB считает, что все значения будут экземплярами B.

Одной из основных целей обобщений является обнаружение потенциальных сбоев типов во время компиляции, а не во время выполнения, что означает, что этот код не должен компилироваться, что на самом деле происходит именно из-за отсутствия дисперсии.

Это немного нелогично, когда вы привыкли к нормальному наследованию, но это имеет смысл. Связка бананов - это не просто сбор фруктов - это сбор бананов .

Java занимает несколько иную позицию в этом вопросе, используя подстановочные знаки со стороны вызывающей стороны - это позволит вам увидеть только сторону «добавления» словаря для DictB, например, поскольку все, что вы добавляете в DictB, будет хорошо в DictA. Хотя дженерики Java сильно отличаются от дженериков .NET ...

0 голосов
/ 29 января 2009

К сожалению нет. Это известное отсутствие поддержки ковариации / контравариантности. CLR поддерживает это, но компиляторы для C # и VB.Net - нет.

Следующая версия C # (4.0) фактически поддерживает это сейчас, но не уверена насчет vb.net. Кроме того, в System.Linq одним из методов расширения является Cast (), который позволит вам преобразовывать коллекцию одного типа в другой. Однако он по-прежнему будет возвращать IEnumerable, поэтому вам нужно немного поработать, но я думаю, что типы ключ-значение будут сложнее, чем коллекции с одним общим типом.

0 голосов
/ 29 января 2009

Это интересный и довольно сложный аспект систем статического типа. Вы ищете термины Ковариантность и Контравариантность.

Язык c # получит это для определенных видов операций над универсальными типами в 4.0, хотя и в несколько ограниченной форме.

У вас это в определенной степени уже есть в форме

object[] x = new string[1];

Это разрешено, потому что массивы обрабатываются ковариантно, что означает, что вы можете затем сделать следующее:

x[0] = new object();

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

Спецификация c # 4.0 все еще не является окончательной, поэтому может быть изменена, но некоторые обсуждения и объяснения см. этот вопрос

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...