简体   繁体   English

在VB.net中转换字典的值类型

[英]Converting Value Type of a Dictionary in VB.net

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

This doesn't work, as the type can't be converted. 这不起作用,因为无法转换类型。 Is this somehow possible? 这可能吗?

No. You're running into the problem of generic variance, which isn't supported in .NET except in a few very particular ways. 不会。您遇到了通用差异的问题,.NET除了少数几种非常特殊的方式不支持。

Here's the reason: after your last line, you've got a single dictionary with two "views" onto it, effectively. 这是原因:在最后一行之后,您将有效地使用一个带有两个“视图”的字典。 Now imagine you wrote: 现在想象一下您写道:

DictA.Add(1, New A())

(Apologies if my VB is slightly off.) That's inserted a "non-B" into the dictionary, but DictB thinks that all the values will be instances of B. (很抱歉,如果我的VB稍微关闭了。)在字典中插入了“非B”,但DictB认为所有值都是B的实例。

One of the main purposes of generics is to catch potential type failures at compile time rather than execution time - which means this code should fail to compile, which indeed it does precisely because of the lack of variance. 泛型的主要目的之一是在编译时而不是在执行时捕获潜在的类型错误-这意味着该代码应该无法编译,而实际上正是由于缺乏差异而导致了这种情况。

It's a bit counter-intuitive when you're used to normal inheritance, but it does make sense. 当您习惯了普通继承时,这有点违反直觉,但这确实是有道理的。 A bunch of bananas isn't just a collection of fruit - it's a collection of bananas . 一束香蕉不仅是水果的集合,还是香蕉的集合。

Java takes a somewhat different stance on this using wildcarding from the caller's side - it would let you see just the "adding" side of the dictionary for DictB, for instance, as anything you add to DictB would be fine in DictA. Java在调用者方面使用通配符对此采取不同的立场-例如,它将使您仅看到DictB字典的“添加”侧,因为添加到DictB中的任何内容在DictA中都可以。 Java's generics are very different to .NET generics though... Java的泛型与.NET泛型非常不同...

This is a interesting, and quite complex aspect of Static type systems. 这是静态类型系统的一个有趣且非常复杂的方面。 The terms you are looking for is Covariance and Contravariance. 您要查找的术语是协方差和逆方差。

The c# language will get this for certain sorts of operations on Generic types in 4.0 though in a somewhat limited form. 尽管在某种程度上是有限的,但c#语言会在4.0中对泛型类型进行某些类型的操作时获得此效果。

You have it to a certain degree already in the form of 您已经在某种程度上以

object[] x = new string[1];

Which is allowed because arrays are treated covariantly, which means that you could then do the following: 之所以允许这样做是因为数组是协变处理的,这意味着您可以执行以下操作:

x[0] = new object();

which would throw an Exception at runtime. 这将在运行时引发异常。 Do you see how the same would apply to you Dictionaries... 您是否看到同样的方法适用于您的字典...

The c# 4.0 spec is still non final so is subject to change but for some discussions and explanations see this question C#4.0规范仍然不是最终版本,因此可能会有所更改,但是对于某些讨论和解释,请参阅此问题

Unfortunately not. 不幸的是没有。 This is a known absence of covariance/contravariance support. 这是众所周知的缺乏协方差/相反方差支持的情况。 The CLR supports it, but the compilers for C# and VB.Net do not. CLR支持它,但是C#和VB.Net的编译器不支持。

The next version of C# (4.0) actually does support it now, but not sure about vb.net. 下一版本的C#(4.0)实际上现在支持它,但是不确定vb.net。 Also, with System.Linq, one of the extension methods is Cast() which would allow you to cast from a collection of one type to another. 另外,对于System.Linq,扩展方法之一是Cast(),它允许您从一种类型的集合转换为另一种类型。 However it will still return IEnumerable so you need to manipulate a little bit, but I think key-value types will be harder than collections with only one generic type. 但是,它将仍然返回IEnumerable,因此您需要进行一些操作,但是我认为键值类型将比仅具有一个泛型类型的集合更难。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM