2012-11-23 30 views
9

Tôi mới sử dụng Generics và gặp rắc rối khi triển khai một mã thực hành nhỏ.Làm cách nào để truyền giá trị int cho thông số loại chung chung tương đương như char?

Tôi đang tạo danh sách được liên kết. Tôi muốn nó lưu trữ giá trị char hoặc int. Vì vậy, tôi quyết định làm cho việc thực hiện chung:

public class Node<T> where T : struct, IConvertible 
{ 
    public Node<T> next = null; 
    public T data = default(T); 

    public Node(T value) { this.data = value; } 
} 

Tôi có một phương pháp mà tạo ra các danh sách liên kết bằng cách tạo ra các giá trị ngẫu nhiên trong khoảng [33.127), chuyển đổi các giá trị cho các loại theo quy định của T (ví dụ nếu 86 là tạo ra và T là Char, sau đó giá trị được lưu trữ trong nút danh sách liên kết sẽ là 'V'; Nếu T là Int32, thì giá trị sẽ đơn giản là 86). Tôi đang phải đối mặt với hai vấn đề:

static Node<IConvertible> CreateList<T>(int len) where T : struct, IConvertible 
    { 
     Random r = new Random((int)DateTime.Now.Ticks); 
     T value = (T)r.Next(33, 127);  // Problem #1 

     Node<T> head = new Node<T>(value); 
     Node<T> n = head; 

     for (int i = 1; i < len; i++) 
     { 
      n.next = new Node<T>(value); 
      n = n.next; 
     } 
     return head; // Problem #2 
    } 

Đây là những vấn đề:

1) Thông thường điều này có thể: (int) value = (char) r.Next (33, 127). Tại sao nếu T là kiểu Char, trình biên dịch nói "Không thể chuyển đổi kiểu 'int' thành 'T'", ngay cả khi tôi đã chỉ định "ở đâu T: struct, IConvertible"?

2) "Không thể chuyển đổi ngầm gõ 'LinkedList.Node<T>' thành 'LinkedList.Node<System.IConvertible>" Nếu T là một trong hai Int32 hoặc Char và cả trong số họ thực hiện IConvertible, cách để cast Node<Int32> hoặc Node<Char>-Node<IConvertible> là gì?

Cảm ơn rất nhiều!

Trả lời

1

Sử dụng

T value = (T)Convert.ChangeType(r.Next(33, 127), typeof(T)); 
2

Việc bạn sử dụng Random để tạo ra một số dữ liệu là loại mâu thuẫn với việc sử dụng Generics. Tôi sẽ tách hai như vậy:

static Node<T> CreateList<T>(int len, Func<T> dataProvider) where T : struct, IConvertible 
{ 
    Node<T> head = new Node<T>(dataProvider()); 
    Node<T> n = head; 

    for (int i = 1; i < len; i++) 
    { 
     n.next = new Node<T>(dataProvider()); 
     n = n.next; 
    } 
    return head; 
} 

mã gọi:

Random r = new Random(); 
Node<char> list = CreateList(10,() => (char)r.Next(33, 127)); 

Vấn đề thứ hai là Node<IConvertible> không được phép bởi struct hạn chế của bạn trên Node<T>. Chỉ cần trả lại Node<T>. Ngay cả khi bạn loại bỏ ràng buộc struct từ Node<T>, nó sẽ không thể trả lại Node<IConvertible> vì các lớp chung không hỗ trợ phương sai.

6

Vấn đề là T có thể là bất kỳ cấu trúc nào, ví dụ: Hướng dẫn, SByte ... hoặc tùy chỉnh-mới-một. và trong khi chúng tôi có thể chắc chắn rằng TstructIConvertible, có không phải là toán tử chuyển kiểu tường minh để

public static explicit operator AnyStruct(int i) 

Vấn đề thứ hai đúc Node<System.IConvertible>-Node<System.IConvertible> là bình thường. Bất kỳ danh sách List<T> không thể được chuyển đổi thành List<System.IConvertible>.

Điều chúng tôi cần là khai báo hiệp phương sai trên giao diện: INode<out T>. Sau đó, INode<T> có thể được chuyển đổi thành INode<System.IConvertible>

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