【问题标题】: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' 有一些永远无法满足的类型约束"。

标签: c# vb.net visual-studio-2008 generics .net-3.5


【解决方案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 只是为了保持一致)。

    【讨论】:

    • 我已尝试按照您的建议更改类型参数的名称,但没有任何区别。好主意。
    猜你喜欢
    • 2013-05-14
    • 1970-01-01
    • 1970-01-01
    • 2016-08-12
    • 1970-01-01
    • 1970-01-01
    • 2018-04-07
    • 1970-01-01
    相关资源
    最近更新 更多