我有这个C#扩展方法,它将扩展 Value 类型为 IList 的任何字典。当我在VB.Net中编写等效代码时,我得到以下编译错误:
“扩展方法'添加'有一些永远无法满足的类型约束”。
我觉得这很令人费解,因为相同的类型约束可以在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
答案 0 :(得分:5)
问题只发生在<System.Runtime.CompilerServices.Extension()>
时。
VB编译器强制要求约束必须仅使用第一个参数进行验证。由于扩展方法的第一个参数(Dictionary(Of KeyType, ListType)
)依赖于第三个参数(ValueType
)通过IList(Of TValue)
约束,因此无法在VB中编译。
答案 1 :(得分:3)
原因在此解释:http://msdn.microsoft.com/en-us/library/bb385206.aspx
在这种情况下,VB编译器可能有点挑剔,因为它必须支持可选参数。 C#(尚未)中没有可选参数。
答案 2 :(得分:1)
请注意,稍有不同:
''' <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 ...))
。
答案 3 :(得分:0)
我怀疑问题在于您使用ValueType作为其中一个类型参数的名称,这是.NET类库(System.ValueType)中的实际类型。我可以想象C#和VB.NET以不同的方式处理它。尝试使用不同的名称,例如TValue(和TKey一致)。