【问题标题】:Converting Value Type of a Dictionary in VB.net在 VB.net 中转换字典的值类型
【发布时间】:2009-01-29 08:11:51
【问题描述】:
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

这不起作用,因为无法转换类型。这有可能吗?

【问题讨论】:

    标签: vb.net dictionary


    【解决方案1】:

    没有。您遇到了泛型差异的问题,除了一些非常特殊的方式外,.NET 不支持该问题。

    原因如下:在你的最后一行之后,你有一个字典,上面有两个“视图”,有效。现在想象一下你写的:

    DictA.Add(1, New A())
    

    (抱歉,如果我的 VB 稍有偏差。)在字典中插入了一个“非 B”,但 DictB 认为所有值都是 B 的实例。

    泛型的主要目的之一是在编译时而不是执行时捕获潜在的类型错误 - 这意味着该代码应该无法编译,而这正是由于缺乏方差而导致的。

    当你习惯了普通的继承时,这有点违反直觉,但它确实是有道理的。一串香蕉不仅仅是水果的集合 - 它是香蕉的集合

    Java 在调用方使用通配符对此采取了一些不同的立场 - 例如,它会让您只看到字典中为 DictB 的“添加”端,因为您添加到 DictB 的任何内容在 DictA 中都可以。不过,Java 的泛型与 .NET 的泛型非常不同......

    【讨论】:

      【解决方案2】:

      这是静态类型系统的一个有趣且相当复杂的方面。 您正在寻找的术语是协变和逆变。

      c# 语言将在 4.0 中对泛型类型进行某些类型的操作,但形式有所限制。

      你已经在某种程度上拥有它

      object[] x = new string[1];
      

      这是允许的,因为数组是协变处理的,这意味着您可以执行以下操作:

      x[0] = new object();
      

      这会在运行时抛出异常。你知道这同样适用于你的字典吗...

      c# 4.0 规范仍未最终确定,因此可能会发生变化,但有关一些讨论和解释,请参阅 this question

      【讨论】:

        【解决方案3】:

        很遗憾没有。这是已知的协方差/逆变支持的缺失。 CLR 支持它,但 C# 和 VB.Net 的编译器不支持。

        下一个版本的 C# (4.0) 现在确实支持它,但不确定 vb.net。 此外,对于 System.Linq,其中一种扩展方法是 Cast(),它允许您从一种类型的集合转换为另一种类型。但是它仍然会返回 IEnumerable,因此您需要进行一些操作,但我认为键值类型会比只有一种泛型类型的集合更难。

        【讨论】:

          猜你喜欢
          • 2013-07-18
          • 2015-07-28
          • 2021-08-29
          • 2013-03-08
          • 1970-01-01
          • 1970-01-01
          • 2021-06-19
          • 2012-01-31
          • 1970-01-01
          相关资源
          最近更新 更多