代码之家  ›  专栏  ›  技术社区  ›  Doctor Jones

C#到VB.Net:为什么转换为VB时无法编译?

  •  7
  • Doctor Jones  · 技术社区  · 17 年前

    我有一个C#扩展方法,可以扩展任何字典,其中 类型是 IList .当我在VB.Net中编写等效代码时,我得到以下编译错误:

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

    我觉得这真的很令人费解,因为 相同的 类型约束 对C#感到满意。

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

    (如果你很好奇,扩展方法旨在使在字典中添加多个值变得简单 单个的 关键(例如一个客户下的多个订单)。但这并不重要,我只关心我在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
    
    4 回复  |  直到 13 年前
        1
  •  5
  •   configurator    17 年前

    问题只会在以下情况下发生 <System.Runtime.CompilerServices.Extension()> 存在。 VB编译器施加了一个限制,即约束必须仅通过第一个参数进行验证。自从扩展方法的第一个参数( Dictionary(Of KeyType, ListType) )取决于第三个论点( ValueType )通过 IList(Of TValue) 约束,这无法在VB中编译。

        2
  •  3
  •   Dirk Vollmar    9 年前

    原因如下: http://msdn.microsoft.com/en-us/library/bb385206.aspx

    在这种情况下,VB编译器可能有点挑剔,因为它必须支持可选参数。C#中还没有可选参数。

        3
  •  1
  •   Mark Hurd    13 年前

    请注意,细微的差异是有效的:

    ''' <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 ...)) .

        4
  •  0
  •   csgero    17 年前

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