C# 到 VB.Net:为啥转换为 VB 时编译失败?

Posted

技术标签:

【中文标题】C# 到 VB.Net:为啥转换为 VB 时编译失败?【英文标题】:C# to VB.Net: Why does this fail to compile when converted to VB?C# 到 VB.Net:为什么转换为 VB 时编译失败? 【发布时间】:2010-09-25 08:40:33 【问题描述】:

我有这个 C# 扩展方法,它可以扩展任何 Value 类型为 IList 的字典。当我在 VB.Net 中编写等效代码时,出现以下编译错误:

“扩展方法 'Add' 有一些永远无法满足的类型约束”。

我觉得这真的很令人费解,因为 same 类型约束可以在 C# 中得到满足。

所以我的问题是:为什么这在 VB 中不起作用?有没有办法让这些相同的类型约束在 VB 中起作用?我是不是在转换代码时出错了?我希望有人能对此有所了解,因为我一直在摸索这个问题。 :)

(如果您好奇,扩展方法旨在简化在 single 键下将多个值添加到字典中(例如一个客户下的多个订单)。但这不重要,我只关心我在 VB 中观察到的令人费解的行为)。

这是可用的 C# 版本:

/// <summary>
/// Adds the specified value to the multi value dictionary.
/// </summary>
/// <param name="key">The key of the element to add.</param>
/// <param name="value">The value of the element to add. The value can be null for reference types.</param>
public static void Add<KeyType, ListType, ValueType>(this Dictionary<KeyType, ListType> thisDictionary, 
                                                     KeyType key, ValueType value)
where ListType : IList<ValueType>, new()

    //if the dictionary doesn't contain the key, make a new list under the key
    if (!thisDictionary.ContainsKey(key))
    
        thisDictionary.Add(key, new ListType());
    

    //add the value to the list at the key index
    thisDictionary[key].Add(value);

这是无法编译的 VB 版本:

''' <summary> 
''' Adds the specified value to the multi value dictionary. 
''' </summary> 
''' <param name="key">The key of the element to add.</param> 
''' <param name="value">The value of the element to add. The value can be null for reference types.</param> 
<System.Runtime.CompilerServices.Extension()> _
Public Sub Add(Of KeyType, ListType As IList(Of ValueType), New, ValueType) _
              (ByVal thisDictionary As Dictionary(Of KeyType, ListType), ByVal key As KeyType, ByVal value As ValueType)
    'if the dictionary doesn't contain the key, make a new list under the key 
    If Not thisDictionary.ContainsKey(key) Then
        thisDictionary.Add(key, New ListType())
    End If

    'add the value to the list at the key index 
    thisDictionary(key).Add(value)
End Sub

【问题讨论】:

它给出的错误是什么? "扩展方法 'Add' 有一些永远无法满足的类型约束"。 【参考方案1】:

这里解释原因:http://msdn.microsoft.com/en-us/library/bb385206.aspx

在这种情况下,VB 编译器可能会更挑剔一些,因为它必须支持可选参数。 C# 中没有可选参数(目前)。

【讨论】:

【参考方案2】:

请注意,略有不同:

''' <summary> 
''' Adds the specified value to the multi value dictionary. 
''' </summary> 
''' <param name="key">The key of the element to add.</param> 
''' <param name="value">The value of the element to add. The value can be null for reference types.</param> 
<System.Runtime.CompilerServices.Extension()> _
Public Sub Add(Of KeyType, ListType As New, IList(Of ValueType), ValueType) _
              (ByVal thisDictionary As Dictionary(Of KeyType, IList(Of ValueType)), ByVal key As KeyType, ByVal value As ValueType)
    'if the dictionary doesn't contain the key, make a new list under the key 
    If Not thisDictionary.ContainsKey(key) Then
        thisDictionary.Add(key, New ListType())
    End If

    'add the value to the list at the key index 
    thisDictionary(key).Add(value)
End Sub

您可以让Dictionary 包含ListType 列表,但它必须声明为(Of ..., IList(Of ...))

【讨论】:

这不会导致New ListType() 调用失败吗?我们失去了指定 ListType 必须具有公共无参数构造函数的约束。 @DoctaJonez 不,ListType As New, IList(Of ValueType) 约束仍然存在。我已经编译了这段代码,但没有测试过。 当然!我没有正确阅读它,我责怪VB语法突出显示效果不佳! ;-)【参考方案3】:

仅当存在&lt;System.Runtime.CompilerServices.Extension()&gt; 时才会出现此问题。 VB 编译器强加了一个限制,即约束必须可以单独使用第一个参数进行验证。由于扩展方法的第一个参数 (Dictionary(Of KeyType, ListType)) 通过 IList(Of TValue) 约束依赖于第三个参数 (ValueType),因此无法在 VB 中编译。

【讨论】:

奇怪的是,他们在 VB 中有这个限制,而在 C# 中没有。这是突出 VB 和 C# 拥有不同开发团队这一事实的情况之一。【参考方案4】:

我怀疑问题在于您使用 ValueType 作为类型参数之一的名称,它是 .NET 类库 (System.ValueType) 中的实际类型。我可以想象 C# 和 VB.NET 以不同的方式处理这个问题。尝试使用不同的名称,例如 TValue(和 TKey 只是为了保持一致)。

【讨论】:

我已尝试按照您的建议更改类型参数的名称,但没有任何区别。好主意。

以上是关于C# 到 VB.Net:为啥转换为 VB 时编译失败?的主要内容,如果未能解决你的问题,请参考以下文章

将 SQL 命令从 vb .net 转换为 C#

如何将 C# 多维列表转换为 VB.Net

如何将带有枚举的 VB.net 接口转换为 C#

需要帮助将 c# 中的 opencv 转换为 vb.net

将 vb.net 类对象转换为 vb.net 中的 JSON 字符串

从 C# 转换为 vb.net 后,它显示错误