2008-12-04 56 views
7

Tôi có phương pháp mở rộng C# này sẽ mở rộng bất kỳ từ điển nào có giá trị Giá trịIList. Khi tôi viết mã tương đương trong VB.Net Tôi nhận được lỗi biên dịch sau:C# để VB.Net: Tại sao điều này không biên dịch khi chuyển đổi sang VB?

"Extension method 'Add' has some type constraints that can never be satisfied".

Tôi tìm thấy điều này thực sự khó hiểu như cùng khó khăn loại thể được thỏa mãn trong C#.

Vì vậy, câu hỏi của tôi là: Tại sao điều này không hoạt động trong VB? Có cách nào để làm cho những hạn chế loại tương tự làm việc trong VB? Tôi đã sai khi chuyển đổi mã? Tôi hy vọng ai đó có thể làm sáng tỏ điều này vì tôi đã gãi đầu vào cái này một lúc. :)

(Trong trường hợp bạn tò mò phương pháp mở rộng được thiết kế để làm cho nó đơn giản để thêm nhiều giá trị vào một cuốn từ điển dưới một đơn chủ chốt (như nhiều đơn đặt hàng dưới một khách hàng). Nhưng điều này là không quan trọng, tôi tôi chỉ quan tâm đến hành vi khó hiểu mà tôi đang quan sát trong VB).

Dưới đây là C# Phiên bản hoạt động:

/// <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); 
} 

Dưới đây là phiên bản VB mà không biên dịch:

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

Lỗi mà nó cung cấp là gì? –

+0

"Phương pháp mở rộng 'Thêm' có một số ràng buộc loại không bao giờ có thể thỏa mãn". –

Trả lời

5

Sự cố chỉ xảy ra khi có <System.Runtime.CompilerServices.Extension()>. Trình biên dịch VB áp đặt một hạn chế rằng các ràng buộc phải được kiểm chứng với đối số đầu tiên một mình. Vì đối số đầu tiên cho phương thức mở rộng (Dictionary(Of KeyType, ListType)) phụ thuộc vào đối số thứ ba (ValueType) qua ràng buộc IList(Of TValue), điều này không thể được biên dịch trong VB.

+1

Thật lạ khi họ có hạn chế này trong VB nhưng không có trong C#. Đây là một trong những tình huống làm nổi bật thực tế là VB và C# có các nhóm phát triển khác nhau. –

0

tôi sẽ nghi ngờ rằng vấn đề là bạn đã sử dụng ValueType làm tên cho một trong các tham số kiểu, là một kiểu thực tế trong thư viện lớp .NET (System.ValueType). Tôi có thể tưởng tượng rằng C# và VB.NET xử lý điều này một cách khác nhau. Hãy thử nó với một tên khác, như TValue (và TKey chỉ để được nhất quán).

+0

Tôi đã thử thay đổi tên của các tham số loại như bạn đề xuất và nó không tạo sự khác biệt. Ý tưởng hay. –

3

Lý do được giải thích ở đây: http://msdn.microsoft.com/en-us/library/bb385206.aspx

Trình biên dịch VB có thể là một chút pickier trong trường hợp này bởi vì nó có để hỗ trợ các thông số tùy chọn. Không có tham số tùy chọn trong C# (chưa).

1

Lưu ý rằng một khác biệt nhỏ hoạt động:

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

Bạn có thể có Dictionary chứa ListType danh sách, nhưng nó phải được khai báo là (Of ..., IList(Of ...)).

+0

Điều đó sẽ không làm cho cuộc gọi 'New ListType()' bị lỗi? Chúng tôi đã bị mất ràng buộc của chúng tôi chỉ định rằng ListType phải có một hàm tạo tham số công khai. –

+0

@DoctaJonez Không, ràng buộc 'ListType As {New, IList (Of ValueType)} vẫn còn đó. Tôi đã biên dịch mã này, nhưng chưa thử nghiệm nó. –

+0

Tất nhiên! Tôi đã không đọc nó đúng cách, tôi đổ lỗi cho thực tế là cú pháp VB làm nổi bật không hoạt động rất tốt! ;-) –

Các vấn đề liên quan